C# Linq2SQL生成的奇怪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

我有一个linq查询,如下所示:(是更大查询的一部分,但这说明了问题所在)

它生成以下SQL:

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]