You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:22:12