EF Core simple GroupBy抛出InvalidOperationException异常



我有两个实体,CoursePurchase,它们之间是一对多的关系。

我想获得给定课程在过去10天内每天的购买次数,这是我所做的,不太复杂:

dbContext.Courses.Where(c => c.Id == [some-id]).Select(c => new
{
PurchasesCountInLastTenDays = c.Purchases
.GroupBy(p => p.PurchasedAt.Date)
.Select(g => new
{
Date = g.Key,
Count = g.Count(),
})
.ToList(),
}).Single();

EF Core (v5.0.9)抛出以下异常:

系统。InvalidOperationException: '无法在投影中翻译集合子查询,因为它使用'Distinct'或'Group By'操作,并且不投影所有需要在客户端生成结果的表的关键列。缺栏:p.Id。要么在投影中添加列,要么重写查询以不使用'GroupBy'/'Distinct'操作。

我用谷歌搜索了这个错误信息,但找不到任何相关信息。我不知道这是什么意思,也不知道它在告诉我应该做什么。

我已经尝试根据分组发生的列更改,相同的错误。我甚至移除了Select(g => ...,但它仍然不起作用。

谢谢你的帮助。

这只是当前EF Core查询限制之一。错误消息末尾的建议有点滑稽,因为显然不能在按其他内容分组的查询中包含键列。重写查询w/oGroupBy/Distinct有时是可能的,但不适合查询由非PK/FK值分组/distinct。

为了保证正确性,所请求的查询形状并不像看起来那么容易生成。因为SQL不支持"集合"。返回结果集的成员——它是统一数据记录的平面序列。您可以尝试使用原始ADO手工执行此操作。. NET,你会看到。

由于主要问题(如错误消息所示)是结果对象中的嵌套集合,因此在这种特殊情况下(如果集合是结果对象的唯一成员)的解决方案是在分组之前平坦化源集。换句话说,直接返回PurchasesCountInLastTenDays列表,而不是作为匿名投影的集合成员。它具有直接的SQL等价,EF Core将很乐意为您翻译并实现它。

var coursePurchasesCountInLastTenDays = dbContext.Courses
.Where(c => c.Id == [some-id]) // filter
.SelectMany(c => c.Purchases) // flatten
.GroupBy(p => p.PurchasedAt.Date) // group
// aggregate
.Select(g => new
{
Date = g.Key,
Count = g.Count(),
})
.ToList();

最新更新