Entity Framework 6 - ORA-00932 同时加入 ToString
Posted
技术标签:
【中文标题】Entity Framework 6 - ORA-00932 同时加入 ToString【英文标题】:Entity Framework 6 - ORA-00932 while joining with ToString 【发布时间】:2018-12-03 16:30:01 【问题描述】:我正在使用 oracle 数据库测试 Entity Framework 6.2,但在尝试通过转换加入多个条件时遇到问题。
我需要将TABLE2_ID (NUMBER)
与TABLE2.ID (VARCHAR2)
匹配,它们是不同的值类型。
问题是 ToString()
方法转换为 TO_NCLOB
而不是 TO_NCHAR
这会起作用。
var query = from table1 in context.TABLE1
join table2 in context.TABLE2 on table1.TABLE2_ID.ToString() equals table2.ID
select new
table1.NAME,
table2.TEXT
;
生成的 SQL 如下所示:
SELECT
1 AS "C1",
"Extent1"."NAME" AS "NAME",
"Extent2"."TEXT" AS "TEXT"
FROM "USER"."TABLE1" "Extent1"
INNER JOIN "USER"."TABLE2" "Extent2" ON
(CASE WHEN ("Extent1"."TABLE2_ID" IS NULL) THEN N''
// At this point I need TO_NCHAR
ELSE TO_NCLOB("Extent1"."TABLE2_ID") END) = "Extent2"."ID"
这会导致:
ORA-00932:不一致的数据类型:预期的 NCHAR 得到了 NCLOB
我知道有很多问题几乎相同的例外,但只有不同的用例,所以请看看我如何解决这个问题。
例如有没有办法覆盖ToString()
SQL 翻译?
主要问题: LINQ to SQL .ToString()
转换为 TO_NCLOB
但我需要 TO_NCHAR
或其他解决方案。
我使用 Visual Studio 2017 和 Oracle Developer Tools for VS2017 12.2.0.11
【问题讨论】:
无法测试,所以我所能做的就是建议尝试替代 LINQ 左外连接语法,例如而不是join table2 in ...
尝试from result in context.TABLE2.Where(table2 => table1.TABLE2_ID != null && table1.TABLE2_ID.Value.ToString() == table2.ID && table2.MATCH == "VALUE").DefaultIfEmpty()
。
@IvanStoev 我为我的问题简化了案例。我尝试了您的代码,但结果是相同的 SQL 翻译。
【参考方案1】:
遗憾的是,.ToString()
在 Oracle Entity Framework 中实现得并不好。所以我得到了这个SO question accepted answer 的解决方法。
安装EntityFramework.Functions
Nuget 包并使用Oracle 内置函数TO_NCHAR
的技巧如下:
public static class OracleFunctions
[Function(FunctionType.BuiltInFunction, "TO_NCHAR")]
public static string ToNChar(this string value) => Function.CallNotSupported<string>();
在 DbContext 中覆盖 OnModelCreating:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Conventions.Add(new FunctionConvention(typeof(OracleFunctions)));
然后我可以像这样完美地使用它:
var query = from table1 in context.TABLE1
join table2 in context.TABLE2 on table1.TABLE2_ID.ToNChar() equals table2.ID
select new
table1.NAME,
table2.TEXT
;
【讨论】:
以上是关于Entity Framework 6 - ORA-00932 同时加入 ToString的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Core 6.0 预览4 性能改进