gpt4 book ai didi

linq - 在 Linq 中使用 Join 和 "Olde Style"pre ANSI join 语法有什么区别?

转载 作者:行者123 更新时间:2023-12-04 15:28:20 25 4
gpt4 key购买 nike

这个问题来自 question我昨天问过为什么在我的实体上使用连接查询会产生极其复杂的 SQL。似乎执行这样的查询:

        var query = from ev in genesisContext.Events
join pe in genesisContext.People_Event_Link
on ev equals pe.Event
where pe.P_ID == key
select ev;

产生了在数据库上运行需要 18 秒的可怕 SQL,而通过 where 子句(有点像 pre-ANSI SQL 语法)加入实体需要不到一秒的时间运行并产生相同的结果
        var query = from pe in genesisContext.People_Event_Link
from ev in genesisContext.Events
where pe.P_ID == key && pe.Event == ev
select ev;

我已经用谷歌搜索过了,但仍然不明白为什么第二个会产生与第一个不同的 SQL。有人可以向我解释一下区别吗?我什么时候应该使用 join 关键字

这是我在查询中使用 Join 时生成的 SQL,运行时间为 18 秒:
SELECT 
1 AS [C1],
[Extent1].[E_ID] AS [E_ID],
[Extent1].[E_START_DATE] AS [E_START_DATE],
[Extent1].[E_END_DATE] AS [E_END_DATE],
[Extent1].[E_COMMENTS] AS [E_COMMENTS],
[Extent1].[E_DATE_ADDED] AS [E_DATE_ADDED],
[Extent1].[E_RECORDED_BY] AS [E_RECORDED_BY],
[Extent1].[E_DATE_UPDATED] AS [E_DATE_UPDATED],
[Extent1].[E_UPDATED_BY] AS [E_UPDATED_BY],
[Extent1].[ET_ID] AS [ET_ID],
[Extent1].[L_ID] AS [L_ID]
FROM [dbo].[Events] AS [Extent1]
INNER JOIN [dbo].[People_Event_Link] AS [Extent2] ON EXISTS (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent3].[E_ID] AS [E_ID]
FROM [dbo].[Events] AS [Extent3]
WHERE [Extent2].[E_ID] = [Extent3].[E_ID] ) AS [Project1] ON 1 = 1
LEFT OUTER JOIN (SELECT
[Extent4].[E_ID] AS [E_ID]
FROM [dbo].[Events] AS [Extent4]
WHERE [Extent2].[E_ID] = [Extent4].[E_ID] ) AS [Project2] ON 1 = 1
WHERE ([Extent1].[E_ID] = [Project1].[E_ID]) OR (([Extent1].[E_ID] IS NULL) AND ([Project2].[E_ID] IS NULL))
)
WHERE [Extent2].[P_ID] = 291

这是使用 ANSI 样式语法生成的 SQL(并且与我自己编写 SQL 时所写的非常接近):
SELECT * FROM Events AS E INNER JOIN People_Event_Link AS PE ON E.E_ID=PE.E_ID INNER JOIN PEOPLE AS P ON P.P_ID=PE.P_ID
WHERE P.P_ID = 291

最佳答案

上述查询都不完全“正确”。在 EF 中,使用关系属性代替上述任一属性通常是正确的。例如,如果在名为 Person.PhoneNumbers 的属性中有一个与 PhoneNumbers 具有一对多关系的 Person 对象,则可以编写:

var q = from p in Context.Person
from pn in p.PhoneNumbers
select pn;

EF 将为您构建连接。

就上述问题而言,生成的SQL之所以不同,是因为表达式树不同,即使它们产生了相同的结果。表达式树映射到 SQL,您当然知道可以编写不同的 SQL,这些 SQL 会产生相同的结果但性能不同。该映射旨在在您编写非常“传统”的 EF 查询时生成合适的 SQL。

但是映射并不聪明,无法采用非常规的查询并对其进行优化。在您的第一个查询中,您声明对象必须是等效的。在第二个中,您声明 ID 属性必须是等效的。我上面的示例查询说“只需获取此记录的详细信息。” EF 主要按照我展示的方式设计,但也能很好地处理标量等价。

关于linq - 在 Linq 中使用 Join 和 "Olde Style"pre ANSI join 语法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1238570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com