Sql server EF6-生成不需要的嵌套查询
我有以下表格:Sql server EF6-生成不需要的嵌套查询,sql-server,linq,entity-framework,Sql Server,Linq,Entity Framework,我有以下表格: MAIN_TBL: Col1 | Col2 | Col3 ------------------ A | B | C D | E | F 以及: 我希望编写以下SQL查询: SELECT M.Col1 FROM MAIN_TBL M LEFT JOIN REF_TBL R ON R.Ref1 = M.Col1 AND R.Ref2 = 'G1' WHERE M.Col3 = 'C' 我编写了以下LINQ
MAIN_TBL:
Col1 | Col2 | Col3
------------------
A | B | C
D | E | F
以及:
我希望编写以下SQL查询:
SELECT M.Col1
FROM MAIN_TBL M
LEFT JOIN REF_TBL R
ON R.Ref1 = M.Col1
AND R.Ref2 = 'G1'
WHERE M.Col3 = 'C'
我编写了以下LINQ查询:
from main in dbContext.MAIN_TBL
join refr in dbContext.REF_TBL
on "G1" equals refr.Ref2
into refrLookup
from refr in refrLookup.DefaultIfEmpty()
where main.Col1 == refr.Col1
select main.Col1
生成的SQL为:
SELECT
[MAIN_TBL].[Col1]
FROM (SELECT
[MAIN_TBL].[Col1] AS [Col1],
[MAIN_TBL].[Col2] AS [Col2],
[MAIN_TBL].[Col3] AS [Col3]
FROM [MAIN_TBL]) AS [Extent1]
INNER JOIN (SELECT
[REF_TBL].[Ref1] AS [Ref1],
[REF_TBL].[Ref2] AS [Ref2],
[REF_TBL].[Ref3] AS [Ref3]
FROM [REF_TBL]) AS [Extent2] ON [Extent1].[Col1] = [Extent2].[Ref1]
WHERE ('G1' = [Extent2].[DESCRIPTION]) AND ([Extent2].[Ref1] IS NOT NULL) AND CAST( [Extent1].[Col3] AS VARCHAR) = 'C') ...
看起来它将一个查询嵌套在另一个查询中,而我只希望它从表中提取。我做错了什么?我可能错了,但在linq查询和sql查询中,尤其是在您的左连接子句中,您似乎没有这样做 如果您想要类似于sql查询的东西,我会选择这个
from main in dbContext.MAIN_TBL.Where(x => x.Col3 == "C")
join refr in dbContext.REF_TBL
on new{n = "G1", c = main.Col1} equals new{n = refr.Ref2, c = refr.Col1}
into refrLookup
from r2 in refrLookup.DefaultIfEmpty()
select main.Col1
顺便说一句,在select子句中不存在的表上进行左联接没有多大意义:如果左联接表中有多个相关项,则只会得到多个相同的Col1…查询看起来完全正常。嵌套对性能没有影响。您是否有实际的性能问题,或者这看起来很可疑?没有,我一个接一个地运行了两个查询,EF生成的查询的成本为80%,而我编写的查询的成本为20%。这些查询在语义上是不同的。它们在不同的列上进行过滤,一个列具有左连接,另一个列具有内部连接。它们是无与伦比的。您似乎认为嵌套会导致性能问题。最终执行计划中不存在此嵌套。它消失了。当我说“零”时,我是按字面意思说的。你确定这真的是你想要的吗?为什么要将join留在一个表上,而这个表在select子句中没有使用?只是为了得到多个相同的结果,在左联接表中有一些东西?顺便说一下,完全同意@usr。如果在linq中执行左侧连接表上的where,这将执行内部连接。谢谢,让我尝试一下。。我确实要在左连接中选择引用列,这将EF查询的成本降低到79%,而常规查询在一批中执行时的成本为21%。他们执行的顺序无关紧要。EF生成的SQl现在是什么样子?2.您的应用程序是否因为该查询而出现了真正的性能问题?它现在有一个左外部连接而不是内部连接,查询看起来仍然一样。在我们将其部署到prod中之前,我无法衡量是否存在性能问题,但我希望出于安全考虑,如果较高的查询成本可能会导致性能问题,我会阻止发送代码。
from main in dbContext.MAIN_TBL.Where(x => x.Col3 == "C")
join refr in dbContext.REF_TBL
on new{n = "G1", c = main.Col1} equals new{n = refr.Ref2, c = refr.Col1}
into refrLookup
from r2 in refrLookup.DefaultIfEmpty()
select main.Col1