LINQ to SQL通过表达式为类似的组生成不同的查询

时间:2016-06-09 10:49:32

标签: c# entity-framework linq linq-to-sql group-by

我注意到在Linq to SQL中使用GroupBy时,在将引用ID作为Key而不是使用实际导航属性作为Key时,结果查询会有所不同。

示例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,很明显除了LEFT JOIN本身之外,永远不会使用[t2]。为什么LINQ to SQL没有检测到它,只是使用与Example#1相同的查询?无论如何都是ID字段组。

1 个答案:

答案 0 :(得分:1)

这看起来像EF的SQL生成器错过了优化查询的机会:事实上,由于[t2]未在外部联接之外使用,因此它可能会被抛弃,同时嵌套select 1}}。

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

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