SQL 从针对 Telerik ORM 的 LINQ 查询生成
SQL Generated From LINQ Query against Telerik ORM
我对使用 LEFT OUTER JOIN 的相当标准的 LINQ 查询生成的 SQL 感到有些困惑。该查询针对的是 Free Telerik Open Access/Data Access 产品。
我写了下面的 LINQ ...
01.var sessionQ = from sessionHdr in headersQ
02. join sessionBody in bodyQ on
03. sessionHdr.ID equals sessionBody.ID into sessionList
04. from sessionJSON in sessionList.DefaultIfEmpty()
05. where sessionHdr.Format == 13
06.
07. select new WITransmitsVP
08. {
09. ...
10. };
将此 LINQ 语法用于 OUTER JOIN 我期望生成的 SQL (ORACLE) 看起来类似于以下内容...
1.SELECT
2. ...
3.
4.FROM "XFEVP"."WI_TRANSMITS_VP" a
5. INNER JOIN "XFEVP"."WI_TRANSMITS_VP_MSG" b ON
6. a."MESSAGE_ID" = b."MESSAGE_ID"
7.WHERE a."MESSAGE_ID" = 60412762;
但是当我记录输出时我看到了...
01.SELECT
02. ...
03.
04.FROM "XFEVP"."WI_TRANSMITS_VP" a
05.WHERE a."MESSAGE_ID" = :p0
06.ORDER BY COL1
07.
08.SELECT
09. ...
10.
11.FROM "XFEVP"."WI_TRANSMITS_VP_MSG" a
12.ORDER BY COL1
我看到两个完全独立的 SELECT 语句,而不是带有 OUTER JOIN 的单个 SELECT。由于每个 table 包含数百万条记录,并且可能正在查询第二个 table 的所有内容,而不仅仅是那些连接到第一个 SELECT 语句结果的内容,因此组件进行调用经过许多分钟的延迟后,最终由于内存问题而崩溃。
为什么我在生成的 SQL 中没有得到实际的 JOIN 语句?是否有解决方法或我只是做错了什么?
解决方案
感谢 EVK 提供答案。事实证明,问题出在我定义 IQueryable 的方式上。我用对 DBContext 集合的引用替换了 IQueryables ...
01.var sessionQ = from sessionHdr in DBContext.SessionHeaders
02. join sessionBody in DBContext.SessionBodies on
03. sessionHdr.ID equals sessionBody.ID into sessionList
04. from sessionJSON in sessionList.DefaultIfEmpty()
05. where sessionHdr.Format == 13
06.
07. select new WITransmitsVP
08. {
09. ...
10. };
这导致生成了以下 SQL ...
SELECT
...
FROM "XFEVP"."WI_TRANSMITS_VP" a
LEFT JOIN "XFEVP"."WI_TRANSMITS_VP_MSG" b ON
(a."MESSAGE_ID" = b."MESSAGE_ID")
WHERE a."FORMAT" = :p0
我的猜测是 headersQ
和 bodyQ
代表一些相对复杂的查询(可能不适合您,但适合您使用的 ORM),因此构建单个查询会遇到一些麻烦他们。因此,它没有抛出一些异常,而是做了一些坏事——将两个查询结果都拉入内存并在那里组合它们。
我对使用 LEFT OUTER JOIN 的相当标准的 LINQ 查询生成的 SQL 感到有些困惑。该查询针对的是 Free Telerik Open Access/Data Access 产品。
我写了下面的 LINQ ...
01.var sessionQ = from sessionHdr in headersQ
02. join sessionBody in bodyQ on
03. sessionHdr.ID equals sessionBody.ID into sessionList
04. from sessionJSON in sessionList.DefaultIfEmpty()
05. where sessionHdr.Format == 13
06.
07. select new WITransmitsVP
08. {
09. ...
10. };
将此 LINQ 语法用于 OUTER JOIN 我期望生成的 SQL (ORACLE) 看起来类似于以下内容...
1.SELECT
2. ...
3.
4.FROM "XFEVP"."WI_TRANSMITS_VP" a
5. INNER JOIN "XFEVP"."WI_TRANSMITS_VP_MSG" b ON
6. a."MESSAGE_ID" = b."MESSAGE_ID"
7.WHERE a."MESSAGE_ID" = 60412762;
但是当我记录输出时我看到了...
01.SELECT
02. ...
03.
04.FROM "XFEVP"."WI_TRANSMITS_VP" a
05.WHERE a."MESSAGE_ID" = :p0
06.ORDER BY COL1
07.
08.SELECT
09. ...
10.
11.FROM "XFEVP"."WI_TRANSMITS_VP_MSG" a
12.ORDER BY COL1
我看到两个完全独立的 SELECT 语句,而不是带有 OUTER JOIN 的单个 SELECT。由于每个 table 包含数百万条记录,并且可能正在查询第二个 table 的所有内容,而不仅仅是那些连接到第一个 SELECT 语句结果的内容,因此组件进行调用经过许多分钟的延迟后,最终由于内存问题而崩溃。
为什么我在生成的 SQL 中没有得到实际的 JOIN 语句?是否有解决方法或我只是做错了什么?
解决方案
感谢 EVK 提供答案。事实证明,问题出在我定义 IQueryable 的方式上。我用对 DBContext 集合的引用替换了 IQueryables ...
01.var sessionQ = from sessionHdr in DBContext.SessionHeaders
02. join sessionBody in DBContext.SessionBodies on
03. sessionHdr.ID equals sessionBody.ID into sessionList
04. from sessionJSON in sessionList.DefaultIfEmpty()
05. where sessionHdr.Format == 13
06.
07. select new WITransmitsVP
08. {
09. ...
10. };
这导致生成了以下 SQL ...
SELECT
...
FROM "XFEVP"."WI_TRANSMITS_VP" a
LEFT JOIN "XFEVP"."WI_TRANSMITS_VP_MSG" b ON
(a."MESSAGE_ID" = b."MESSAGE_ID")
WHERE a."FORMAT" = :p0
我的猜测是 headersQ
和 bodyQ
代表一些相对复杂的查询(可能不适合您,但适合您使用的 ORM),因此构建单个查询会遇到一些麻烦他们。因此,它没有抛出一些异常,而是做了一些坏事——将两个查询结果都拉入内存并在那里组合它们。