LINQ to SQL 为相似的分组依据表达式生成不同的查询

LINQ to SQL generates a different query for similar group by expressions

我注意到,在 Linq 中使用 GroupBy 到 SQL 时,提供参考 ID 作为键与使用实际导航 属性 作为键时,结果查询存在差异。

示例 1:

Employees.GroupBy(x => x.CompanyId).Select(g => g.Count())

结果SQL:

SELECT COUNT(*) AS [value]
FROM [Employees] AS [t0]
GROUP BY [t0].[CompanyId]

示例 2:

Employees.GroupBy(x => x.Company).Select(g => g.Count())

结果SQL:

SELECT [t1].[value]
FROM (
    SELECT COUNT(*) AS [value], [t0].[DivisionDeductionID]
    FROM [CheckDeductions] AS [t0]
    GROUP BY [t0].[DivisionDeductionID]
) AS [t1]
LEFT OUTER JOIN [DivisionDeductions] AS [t2] ON [t2].[DivisionDeductionID] = [t1].[DivisionDeductionID]

查看示例 #2,很明显 [t2] 除了 LEFT JOIN 本身之外从未使用过。为什么 LINQ to SQL 没有检测到它而只是使用与示例 #1 相同的查询?无论如何它按 ID 字段分组。

这看起来像 EF 的 SQL 生成器错过了优化查询的机会:事实上,由于 [t2] 没有在外部连接之外使用,它可能会被丢弃,连同嵌套的select.

似乎 EF 编写者为 [t2] 添加了一个连接,因为他们不想区分情况 (1) 当导航 属性 仅用于其 PK(因此相应的FK 可以代替它使用)和 (2) 查询实际从中提取其他字段的情况。

这种做法是完全合理的,因为 RDBMS 无论如何都会优化掉不必要的连接。