如何强制Linq-To-Sql生成Outer Apply实现关联计数?
如何让LINQ在统计子表数量时生成OUTER APPLY的SQL?
我最近在写LINQ查询时遇到了性能瓶颈:想要获取主表TekMas的TekNr列,以及每条主表记录对应的子表TekRev的记录数列表。目前用常规LINQ写法生成的SQL用了嵌套子查询,耗时高达15秒;但我手动编写的带OUTER APPLY的SQL,执行时间不到1秒,性能差异非常明显。
当前LINQ代码及生成的SQL
LINQ代码
TekMas.Select(x => new {x.TekNr,Cnt = x.TekRev.Count})
生成的SQL
SELECT [Extent1].[TekMasID] AS [TekMasID], [Extent1].[TekNr] AS [TekNr], (SELECT COUNT(1) AS [A1] FROM [dbo].[TekRev] AS [Extent2] WHERE [Extent1].[TekMasID] = [Extent2].[TekMasID]) AS [C1] FROM [dbo].[TekMas] AS [Extent1]
期望生成的SQL
SELECT TekMas.TekNr, RevCnt.Cnt FROM TekMas OUTER APPLY ( SELECT COUNT (TekRevID) AS Cnt FROM TekRev WHERE TekRev.TekMasID = TekMas.TekMasID) RevCnt;
已知的FirstOrDefault生成OUTER APPLY示例
我了解到使用FirstOrDefault的时候,LINQ会生成OUTER APPLY语句,比如下面的代码:
LINQ代码
TekMas.Select(x => new { x.TekNr, Cnt = x.TekRev.FirstOrDefault() }) .Select(x => new { x.TekNr, x.Cnt.TekRevID, x.Cnt.TekRevInf })
生成的SQL
SELECT [Extent1].[TekMasID] AS [TekMasID], [Extent1].[TekNr] AS [TekNr], [Limit1].[TekRevID] AS [TekRevID], [Limit1].[TekRevInf] AS [TekRevInf] FROM [dbo].[TekMas] AS [Extent1] OUTER APPLY (SELECT TOP (1) [Extent2].[TekRevID] AS [TekRevID], [Extent2].[TekRevInf] AS [TekRevInf] FROM [dbo].[TekRev] AS [Extent2] WHERE [Extent1].[TekMasID] = [Extent2].[TekMasID] ) AS [Limit1]
现在我想请教的是:在使用Count统计子表记录数时,怎么让LINQ像FirstOrDefault一样生成OUTER APPLY语句,而不是嵌套子查询呢?
内容的提问来源于stack exchange,提问作者Zer0ne
相关产品推荐
相关产品推荐

