为什么LINQ to SQL将GroupBy转换为多个查询

jno*_*ovo 9 c# linq sql-server linq-to-sql

我注意到甚至比使用GroupBy的更简单的LINQ查询也被转换为与组密钥一样多的SQL查询.我没有找到任何解释为什么会发生这种情况或我如何避免它.

例如,查询:

from p in People group p by p.Name into g select g
Run Code Online (Sandbox Code Playgroud)

被翻译成selects列的不同值Name,就像这个:

-- Region Parameters
DECLARE @x1 VarChar(20) SET @x1 = 'John'
-- EndRegion
SELECT [t0].[Name], [t0].[SurName]
FROM [People] AS [t0]
WHERE ((@x1 IS NULL) AND ([t0].[Name] IS NULL)) 
     OR ((@x1 IS NOT NULL) AND ([t0].[Name] IS NOT NULL) AND (@x1 = [t0].[Name]))
GO
Run Code Online (Sandbox Code Playgroud)

但是,如果我把整个表带到内存中,比如调用AsEnumerable(),

from p in People.AsEnumerable() group p by p.Name into g select g
Run Code Online (Sandbox Code Playgroud)

只发出一个select,检索所有行,然后LINQ在内存中执行分组.

我发现这种行为相当混乱和容易出错,因为我经常发现自己在不同的语句中编写复杂的查询,我必须小心地调用AsEnumerableToList在执行之前GroupBy或我的性能降低.更糟糕的是,它迫使我完成LINQ to SQL查询并继续LINQ to Objects.

我已经使用LINQ to EntitiesLINQ to SQL(通过LINQPad)DBMS进行了测试 SQL Server.

我错过了什么吗?这是设计还是以任何方式编写LINQ查询,GROUP BY使用SQL 而不是生成多个单独的查询?

Adu*_*cci 3

您需要更改您的 select 语句,使其对 SQL 更加友好。

改变:select g

像这样的事情:

select new
{
  g.Key,
  Count = g.Count(),
};
Run Code Online (Sandbox Code Playgroud)