ODAC 11.2 版本 4 (11.2.0.3.0) 抛出“Oracle 11.2.0.2.0 不支持 APPLY”例外

发布于 2024-12-27 12:56:49 字数 1649 浏览 1 评论 0原文

我将实体框架与 Oracle 刚刚发布的新 ODAC 结合使用。

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

下面是一个示例:

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 生成的查询:

test1Query:

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)

提前致谢。

I'm using Entity Framework with the new ODAC that oracle just released.

My problem is that some of my queries that were working in previous beta releases stopped working in this new release version.

Here's an example:

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();

While test1 returns the currect result, test2 throws an oracle exception 'ORA-00905: missing keyword' with message: 'Oracle 11.2.0.2.0 does not support APPLY'.

I don't want to re-test all of my methods. Is there a way to tell EF not to use apply?

Here are the queries that EF is generating:

test1Query:

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)

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄暮涼年 2025-01-03 12:56:49

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

The Telerik OpenAccess ORM does not use the APPLY statement. I had the same issue on a nested group query. When I built the OA model, the query ran great!

(り薆情海 2025-01-03 12:56:49

您尝试过 Oracle 12c 吗?

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

阅读应该有效。

Have you tried Oracle 12c?

Here
https://forums.oracle.com/message/10168766#10168766

read that should works.

北风几吹夏 2025-01-03 12:56:49

这仅适用于 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,这将生成重复项。在这种情况下,你需要对此进行明确的射击。这不会在大量行上产生超级出色的性能。数量少应该没问题。

This will only work in 12c. In 11g you have to re-write the query.

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;

This will generate duplicates if you have more than one active SYS_UTILIZADOR. You would need to fire distinct on that in that case. This will not result in super great performance on large number of rows. Should be OK on a small number.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文