如果您对将数据加载到内存中没有问题,一个简单的解决方案是在Addresses 之后添加.ToList() 或.AsEnumerable():
from a in Addresses.ToList() // or .AsEnumerable()
group a by new {a.StreetName, a.StreetNumber} into agrp
where agrp.Count() > 3
from aitem in agrp
select aitem
请注意,这(在 SqlServer 中)转换为:
SELECT [a].[Id], [a].[StreetName], [a].[StreetNumber]
FROM [Addresses] AS [a]
在 EF Core 中,GroupBy(在许多情况下)不翻译为 SQL,而是在内存中运行。
(为避免意外将大量数据加载到内存中,EF 将抛出异常,除非调用 .ToList() 或 .AsEnumerable() 以表明这是故意的。)
(...) 由于没有数据库结构可以表示 IGrouping,GroupBy 运算符在大多数情况下没有翻译。当聚合运算符应用于每个返回标量的组时,可以将其转换为关系数据库中的 SQL GROUP BY。 (...)
-Complex query operators, GroupBy
该文章还有一个查询示例,该查询转换为group by,并带有Count 上的过滤器(包括在下面)。
不幸的是,该示例并未完全涵盖问题中的示例。它不会返回相关的地址对象,只返回分组键和计数。
var query = from p in context.Set<Post>()
group p by p.AuthorId into g
where g.Count() > 0
orderby g.Key
select new
{
g.Key,
Count = g.Count()
};
SELECT [p].[AuthorId] AS [Key], COUNT(*) AS [Count]
FROM [Posts] AS [p]
GROUP BY [p].[AuthorId]
HAVING COUNT(*) > 0
ORDER BY [p].[AuthorId]