ODP.NET / EF6 - WHERE 子句中的 CHAR 数据类型

Posted

技术标签:

【中文标题】ODP.NET / EF6 - WHERE 子句中的 CHAR 数据类型【英文标题】:ODP.NET / EF6 - CHAR datatype in WHERE clause 【发布时间】:2015-01-30 21:02:32 【问题描述】:

我正在使用 EF6 和 ODP.NET 开始一个项目,但在执行基于固定长度 CHAR 列的查找时遇到问题。

以下代码不返回任何结果,即使该用户存在于数据库中。

using (var context = new Entities())
 
   var search = "testuser";
   var result = context.Users
                .Where(u => u.UserName == search)
                .FirstOrDefault();
  

我知道我可以通过填充搜索字符串或修剪数据库列来解决此问题,但我正在寻找替代解决方案。

我注意到,如果我直接使用 OracleConnection/OracleCommand 执行查询,那么它可以工作。是否有属性或任何我可以添加到实体类以使 ODP.NET 将变量绑定为 OracleDbType.Char 的内容?

基本上,我正在寻找一种从 EF6 重现以下行为的方法:

var cmd = new OracleCommand("SELECT * FROM users WHERE user_name = :p0", conn);
cmd.Parameters.Add(":p0", OracleDbType.Char).Value = "testuser";

我还使用 Devart 的 dotConnect Oracle 驱动程序进行了测试。使用该驱动程序,我可以通过添加以下代码行成功进行查找。不过,我更愿意在 dotConnect 上使用 ODP.NET。 ODP.NET 似乎忽略了这个属性,因为它在使用 ODP.NET 时没有效果。是否存在 ODP.NET 可以识别的等效项?

modelBuilder.Entity<Users>()
            .Property(u => u.UserName
            .IsFixedLength();

如果可以的话,我会将列类型更改为 VARCHAR2 并洗手,但不幸的是,目前这不是一个选项。非常感谢您提供的任何帮助!

【问题讨论】:

你能找出你的LINQ语句生成了什么sql吗? 如果这与我遇到的问题类似,SQL 将如下所示:SELECT "Extent1"."USERNAME" AS "USERNAME", FROM "USERS" "Extent1" WHERE ("Extent1"."USERNAME" = :p__linq__0) AND (ROWNUM &lt;= (1)) 绑定变量最终使用了错误的列数据类型:p__linq__0: 'testuser' (Type = Object)跨度> 我之前评论中的SQL是使用以下modelBuilder配置生成的:modelBuilder.Entity&lt;Users&gt;() .Property(u =&gt; u.UserName) .IsFixedLength() .HasMaxLength(10) .HasColumnType("CHAR") .IsUnicode(false); 【参考方案1】:

将 Oracle 命令替换为

SELECT * FROM users WHERE cast(user_name as varchar2(20)) = :p0

您可以使用 CAST 将大多数数据类型转换为 Oracle 中的大多数其他数据类型。 CHAR 数据类型很难使用(由于某种原因不推荐使用),将其转换为 varchar2(xx) 是最佳选择。

【讨论】:

以上是关于ODP.NET / EF6 - WHERE 子句中的 CHAR 数据类型的主要内容,如果未能解决你的问题,请参考以下文章

实体框架:Count() 在大型 DbSet 和复杂的 WHERE 子句上非常慢

EF 6.x,LINQ-to-SQL和原始SQL子句

在 Oracle Merge 语句的 Using 子句中指定参数

ODP.NET 过程编译

ODP.Net 数组绑定异常处理

ODP.NET TNS:无法解决错误