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 <= (1))
绑定变量最终使用了错误的列数据类型:p__linq__0: 'testuser' (Type = Object)
跨度>
我之前评论中的SQL是使用以下modelBuilder配置生成的:modelBuilder.Entity<Users>() .Property(u => 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 子句上非常慢