C# Linq2SQL生成的奇怪SQL
我有一个linq查询,如下所示:(是更大查询的一部分,但这说明了问题所在) 它生成以下SQL:C# Linq2SQL生成的奇怪SQL,c#,sql,linq,linq-to-sql,C#,Sql,Linq,Linq To Sql,我有一个linq查询,如下所示:(是更大查询的一部分,但这说明了问题所在) 它生成以下SQL: SELECT [t0].[pkGuaranteeId], [t3].[Sum] AS [Sum], [t3].[CurrencyId] AS [CurrencyId], [t3].[ExpectedDate] AS [ExpectedDate2] FROM [dbo].[tblGuarantee] AS [t0] CRO
SELECT [t0].[pkGuaranteeId],
[t3].[Sum] AS [Sum],
[t3].[CurrencyId] AS [CurrencyId],
[t3].[ExpectedDate] AS [ExpectedDate2]
FROM [dbo].[tblGuarantee] AS [t0]
CROSS APPLY ((SELECT NULL AS [EMPTY]) AS [t1]
OUTER APPLY (SELECT TOP (1) [t2].[Sum],
[t2].[CurrencyId],
[t2].[ExpectedDate]
FROM [dbo].[tblGuaranteeDevaluation] AS [t2]
WHERE ( [t2].[fkGuaranteeId] = [t0].[pkGuaranteeId] )
AND ( [t2].[Date] IS NULL )
ORDER BY [t2].[ExpectedDate]) AS [t3])
ORDER BY [t3].[ExpectedDate] -- Why here?
我的问题是,为什么最后一个订单在那里?在我更大的查询中,这确实会影响性能,我无法理解为什么需要它。
此外,如果有任何关于以更好的方式编写此文档的提示,我们将不胜感激。在查询中,您正在按
from gd in tblGuaranteeDevaluations
where gd.fkGuaranteeId == guarantee.pkGuaranteeId &&
gd.Date == null
orderby gd.ExpectedDate ascending
这使得内部查询在内部块中按顺序执行
SELECT TOP (1) [t2].[Sum], [t2].[CurrencyId], [t2].[ExpectedDate]
FROM [dbo].[tblGuaranteeDevaluation] AS [t2]
WHERE ([t2].[fkGuaranteeId] = [t0].[pkGuaranteeId]) AND ([t2].[Date] IS NULL)
ORDER BY [t2].[ExpectedDate]
但是你要“连接”两个不同的集合,空集合和内部块集合,为了确保顺序,代码必须将另一个顺序按,用于“连接”的结果集,因此为什么顺序在外部集合中,是自动代码生成的,但是因为集合已经排序,最后一次下单不应降低性能 如果使用Take(1)
调用切换DefaultIfEmpty()
,会发生什么?用一个FirstOrDefault
调用来替换两者怎么样?使用让nextextdev=…
而不是在…
中使用nextextdev的怎么样
为我做最后一件事。。。将order by
放在投影中似乎向查询的其余部分传递了这样一种信息,即您希望整个事情都按它排序。相反,请查看是否可以从有序源中选择它。IE:来自TblGuaranteEvaluations.OrderBy(t=>t.ExpectedDate)中的gd
在查询中,您正在执行以下操作:
orderby gd.ExpectedDate升序
,这反映在生成的SQL中。我仍然不明白。如果我通过删除最后一个订单,我将得到与使用它相同的结果(无序)。另外,如果我删除“空集”(删除.DefaultIfEmpty()
),它仍然会生成订单。无序或订单结果来自sql引擎,可能返回相同的结果,也可能不返回。另一方面,它仍然通过自动代码生成订单。显然,orderby
是自动代码生成。但问题是为什么。没有理由让它出现在那里,我也不希望结果集被排序。我觉得你的回答不清楚。如果你将DefaultIfEmpty()
与Take(1)
通话切换,会发生什么?用一个FirstOrDefault
调用来替换两者怎么样?如果只使用让nextextdev=…
而不是在…
中使用nextextdev的,怎么样?@SPFiredrake我尝试过的所有好建议。删除DefaultIfEmpty()
不会删除外部订单(也不会生成相同的结果集)。使用let..
是我的第一选择,但这会为select中的每个属性生成一个到内部查询的左连接(在本例中为4),因此情况更糟。只执行FirstOrDefault
将只适用于let解决方案。请为我尝试最后一件事。。。在转换中按
排序似乎向查询的其余部分传递了这样一种信息,即您希望整个查询按该顺序排序。相反,请查看是否可以从有序源中选择它。IE:来自tblGuaranteeDevaluations.OrderBy中的gd(t=>t.ExpectedDate)
。但这应该只生成一个内部订单,外部订单在那里做什么?tblGuaranteeDevaluations.OrderBy中的gd尝试了(t=>…
,正如您所建议的,但不幸的是,这会生成相同的SQL。@Magnus不确定该告诉您什么。我尝试在本地数据库上执行类似的查询,但似乎也不喜欢。出于某种原因,它只是不想在没有对外部查询排序的情况下对top 1执行交叉应用
(这绝对是错误的行为)。祝你好运,我会密切关注,看看是否有什么可以帮助你的。谢谢你的意见!如果我能自己解决,我会添加一个答案。
SELECT TOP (1) [t2].[Sum], [t2].[CurrencyId], [t2].[ExpectedDate]
FROM [dbo].[tblGuaranteeDevaluation] AS [t2]
WHERE ([t2].[fkGuaranteeId] = [t0].[pkGuaranteeId]) AND ([t2].[Date] IS NULL)
ORDER BY [t2].[ExpectedDate]