SQL转Entity Framework计数分组

124

我需要将这个SQL语句翻译成一个Linq-Entity查询...

SELECT name, count(name) FROM people
GROUP by name

如果有人想要进行group by + join rows data,请参考 https://dev59.com/3mcs5IYBdhLWcg3w0HIa - yu yang Jian
5个回答

230

查询语法

var query = from p in context.People
            group p by p.name into g
            select new
            {
              name = g.Key,
              count = g.Count()
            };

方法语法

var query = context.People
                   .GroupBy(p => p.name)
                   .Select(g => new { name = g.Key, count = g.Count() });

25

编辑:EF Core 2.1终于支持GroupBy操作了

但是在控制台/日志中一定要留意错误信息。如果你看到通知说无法将查询转换为 SQL 并且将在本地求值,那么你可能需要重写它。


Entity Framework 7(现已更名为Entity Framework Core 1.0 / 2.0)目前还不支持将GroupBy()翻译成生成的 SQL 的GROUP BY(即使在最终的1.0版本中,它也不会支持)。任何分组逻辑都会在客户端上运行,这可能会导致加载大量数据。

最终编写的代码将自动开始使用 GROUP BY,但现在如果将未分组的整个数据集加载到内存中会导致性能问题,则需要非常谨慎。

对于这种情况,您将不得不手动编写 SQL 并通过 EF 执行它。

如有疑问,请启动 Sql Profiler 并查看生成的内容 - 这也许是您一直应该做的。

https://blogs.msdn.microsoft.com/dotnet/2016/05/16/announcing-entity-framework-core-rc2


6
谢谢提醒。 - Jacob Stamm
4
也就是说,1.1 版本中没有分组功能。 - Simon_Weaver
5
我放弃了。 - Simon_Weaver
4
宣布2.1。 - Yush0
1
这可能会误导人,我认为重要的是更新您的答案并明确提到EF 7之前的版本支持分组。这个回答更像是对OP问题的评论,而不是实际答案,当单独阅读时会产生误导(并被解释为对OP的答案,但实际上不是)。阅读此内容时,人们可能会产生错误的印象,即即使EF 7也不支持分组,而显然早期版本不支持分组,这是不正确的。 - BornToCode
它是在EF Core 2中实现的。但是,如果我使用除了.GroupBy(x => x.OfferId, (key, list) =>....)之外的其他GroupBy,就会遇到包含(includes)的问题。 - Yul S

18

一个有用的扩展是将结果收集到 Dictionary 中以便快速查找(例如在循环中):

var resultDict = _dbContext.Projects
    .Where(p => p.Status == ProjectStatus.Active)
    .GroupBy(f => f.Country)
    .Select(g => new { country = g.Key, count = g.Count() })
    .ToDictionary(k => k.country, i => i.count);

最初的来源在这里: http://www.snippetsource.net/Snippet/140/groupby-and-count-with-ef-in-c


10
以下是.NET Core 2.1中分组的简单示例:
var query = this.DbContext.Notifications
            .Where(n => n.Sent == false)
            .GroupBy(n => new { n.AppUserId })
            .Select(g => new { AppUserId = g.Key, Count =  g.Count() });

var query2 = from n in this.DbContext.Notifications
            where n.Sent == false
            group n by n.AppUserId into g
            select new { id = g.Key,  Count = g.Count()};

这两个翻译的含义是相同的:

SELECT [n].[AppUserId], COUNT(*) AS [Count]
FROM [Notifications] AS [n]
WHERE [n].[Sent] = 0
GROUP BY [n].[AppUserId]

如何在 var query 中访问这些字段? - user1735921

2
使用EF 6.2对我来说有效。
  var query = context.People
               .GroupBy(p => new {p.name})
               .Select(g => new { name = g.Key.name, count = g.Count() });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接