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 2017Oracle 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 6 暂时禁用拦截

Entity Framework Core 6.0 预览4 性能改进

Entity Framework 6 开发系列 目录

添加 [DataContract] 到 Entity Framework 6.0 POCO Template

从 Entity Framework 5 升级到 6

如何扩展 Entity Framework 6 模型