我注意到在Linq to SQL中使用GroupBy时,在将引用ID作为Key而不是使用实际导航属性作为Key时,结果查询会有所不同。
Employees.GroupBy(x => x.CompanyId).Select(g => g.Count())
结果SQL:
SELECT COUNT(*) AS [value]
FROM [Employees] AS [t0]
GROUP BY [t0].[CompanyId]
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,很明显除了LEFT JOIN本身之外,永远不会使用[t2]。为什么LINQ to SQL没有检测到它,只是使用与Example#1相同的查询?无论如何都是ID字段组。
答案 0 :(得分:1)
这看起来像EF的SQL生成器错过了优化查询的机会:事实上,由于[t2]
未在外部联接之外使用,因此它可能会被抛弃,同时嵌套select
1}}。
似乎EF编写者为[t2]
添加了一个连接,因为当导航属性仅用于其PK时,他们不想区分情况(1)(因此相应的FK可以在其中使用(2)查询实际从中拉出其他字段的情况。
这种做法是完全合理的,因为RDBMS无论如何都会优化不必要的连接。