EF Core 2中GroupBy内Count谓词被忽略问题咨询
这大概率是EF Core 2.x早期版本的查询翻译bug
没错,你遇到的这个问题确实很可能是EF Core 2.0.x和2.1预览版2中的已知查询翻译缺陷。我之前也见过类似的案例:当在GroupBy后的Select里嵌套使用Where+Count()时,EF Core的查询翻译器会错误地忽略Where的谓词,导致生成的SQL没有带上IsSpecial = false的过滤条件,最终统计了分组内的所有子项数量。
验证方法
你可以通过查看EF Core生成的SQL来确认这一点——2.x版本可以通过启用日志输出SQL,要是用更高版本的话可以直接调用query.ToQueryString()。如果看到统计部分是COUNT(*),而非COUNT(CASE WHEN IsSpecial = 0 THEN 1 END)或者带对应过滤条件的统计语句,那就能实锤是翻译bug了。
临时解决办法
在没法立刻升级版本的情况下,可以用这两种方式规避:
- 提前过滤再分组:把
IsSpecial == false的过滤逻辑移到GroupBy之前,这样分组时就只包含需要统计的项,直接用Count()即可:
var result = query<Items>() .Where(x => x.Id == someId) .SelectMany(x => x.SubItems) .Where(y => y.IsSpecial == false) // 提前过滤不符合条件的项 .GroupBy(x => x.SubItemId) .Select(x => new ItemModel { SubItemId = x.Key, SpecialItemCount = x.Count(), }) .ToList();
- 用Aggregate替代Count:通过
Aggregate手动计数,强制EF Core正确翻译逻辑:
var result = query<Items>() .Where(x => x.Id == someId) .SelectMany(x => x.SubItems) .GroupBy(x => x.SubItemId) .Select(x => new ItemModel { SubItemId = x.Key, SpecialItemCount = x.Aggregate(0, (total, item) => item.IsSpecial == false ? total + 1 : total), }) .ToList();
彻底解决建议
这个bug在EF Core 2.1正式版以及后续的版本中已经被官方修复了,如果项目条件允许,直接升级到更高版本的EF Core是最一劳永逸的办法。
内容的提问来源于stack exchange,提问作者neko_code
相关产品推荐
相关产品推荐

