【问题标题】:ODAC 11.2 Release 4 (11.2.0.3.0) throwing "Oracle 11.2.0.2.0 does not support APPLY" exceptionODAC 11.2 Release 4 (11.2.0.3.0) 抛出“Oracle 11.2.0.2.0 不支持 APPLY”异常
【发布时间】:2012-02-12 03:10:34
【问题描述】:

我正在使用 Entity Framework 和 oracle 刚刚发布的新 ODAC。

我的问题是,我在以前的 beta 版本中运行的一些查询在这个新版本中停止运行。

这是一个例子:

IQueryable<SYS_PERFIL> query1 = m.DBContext.SYS_PERFIL.Where(T => T.SYS_UTILIZADOR.Where(TT => TT.ACTIVO == 1).Count() > 0);

IQueryable<SYS_PERFIL> query2 = m.DBContext.SYS_PERFIL.Where(T => T.SYS_UTILIZADOR.FirstOrDefault(TT => TT.ACTIVO == 1) != null);

string test1Query = ((System.Data.Objects.ObjectQuery)query1).ToTraceString();

string test2Query = ((System.Data.Objects.ObjectQuery)query2).ToTraceString();

var test1 = query1.ToList();

var test2 = query2.ToList();

当 test1 返回正确的结果时,test2 抛出一个 oracle 异常“ORA-00905:缺少关键字”,并显示消息:“Oracle 11.2.0.2.0 不支持 APPLY”。

我不想重新测试我的所有方法。有没有办法告诉EF不要使用apply?

以下是 EF 生成的查询:

测试1查询:

SELECT "Project1"."PERFIL_ID" AS "PERFIL_ID" FROM ( SELECT "Extent1"."PERFIL_ID" AS PERFIL_ID", (SELECT COUNT(1) AS "A1" FROM "SMI2012"."SYS_UTILIZADOR" "Extent2" WHERE (("Extent1"."PERFIL_ID" = "Extent2"."PERFIL_ID") AND (1 = "Extent2"."ACTIVO"))) AS "C1"
 FROM "SMI2012"."SYS_PERFIL" "Extent1")  "Project1" WHERE ("Project1"."C1" > 0)

test2Query:

SELECT "Extent1"."PERFIL_ID" AS "PERFIL_ID" FROM  "SMI2012"."SYS_PERFIL" "Extent1" CROSS APPLY  (SELECT "Extent2"."PERFIL_ID" AS "PERFIL_ID", "Extent2"."ACTIVO" AS "ACTIVO", "Extent2"."USER_ID" AS "USER_ID" FROM "SMI2012"."SYS_UTILIZADOR" "Extent2" WHERE (("Extent1"."PERFIL_ID" = "Extent2"."PERFIL_ID") AND (1 = "Extent2"."ACTIVO")) AND (ROWNUM <= (1) ) ) "Element1" WHERE ("Element1"."USER_ID" IS NOT NULL)

提前致谢。

【问题讨论】:

  • 这个问题你解决了吗?如果我尝试在投影中使用 FirstOrDefault,我会遇到同样的问题。
  • 假设您并不关心是否获得第一条记录,您可以使用 .Min 而不是 .FirstOrDefault 。

标签: c# entity-framework entity-framework-4 odp.net odac


【解决方案1】:

Telerik OpenAccess ORM 不使用 APPLY 语句。我在嵌套组查询中遇到了同样的问题。当我构建 OA 模型时,查询运行良好!

【讨论】:

    【解决方案2】:

    您尝试过 Oracle 12c 吗?

    这里 https://forums.oracle.com/message/10168766#10168766

    阅读应该可以。

    【讨论】:

      【解决方案3】:

      这仅适用于 12c。在 11g 中,您必须重新编写查询。

      IQueryable<SYS_PERFIL> query2 = from one in m.DBContext.SYS_PERFIL
        join two in m.DBContext.SYS_UTILIZADOR on one.COL1 equals two.COL1
        where two.ACTIVO == 1
        select one;
      

      如果您有多个活动的 SYS_UTILIZADOR,这将生成重复项。在这种情况下,您需要对此进行区分。这不会在大量行上产生超强的性能。小数应该没问题。

      【讨论】:

        猜你喜欢
        • 2015-06-24
        • 1970-01-01
        • 1970-01-01
        • 2020-09-02
        • 1970-01-01
        • 1970-01-01
        • 2020-06-22
        • 2010-12-04
        • 1970-01-01
        相关资源
        最近更新 更多