You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core中GroupBy与Where的LINQ表达式翻译问题

解决方案:避免EF Core 7分组翻译问题,实现服务器端评估

问题根源

你遇到的是EF Core 7的已知限制:当查询返回IGrouping对象时,EF无法将整个表达式完全翻译成SQL,会触发客户端评估;而统计数量的方法能正常工作,是因为最终只返回聚合后的数值,不需要序列化分组对象。

修改获取重复条目列表的方法

不要直接返回分组,而是先筛选出拥有多个条目的OwnerId,再用这些ID关联回原表获取具体条目,全程在服务器端执行:

public async Task<IEnumerable<ItemType>> GetItemsWithDuplicateOwners()
{
    // 第一步:查询所有拥有重复条目的OwnerId(服务器端执行)
    var duplicateOwnerIds = await GetItemsSecureAsync()
        .Where(item => item.OwnerId != null)
        .GroupBy(item => item.OwnerId)
        .Where(group => group.Count() > 1)
        .Select(group => group.Key)
        .ToListAsync();

    // 第二步:用筛选出的ID获取对应条目(服务器端执行)
    return await GetItemsSecureAsync()
        .Where(item => duplicateOwnerIds.Contains(item.OwnerId))
        .ToListAsync();
}

修复扩展方法

原扩展方法的GroupBy+SelectMany写法在EF Core 7中翻译存在问题,改成先取重复Key再过滤的逻辑:

public static async Task<IEnumerable<T>> NonDistinctAsync<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> keySelector)
    where TKey : notnull
{
    var duplicateKeys = await source
        .GroupBy(keySelector)
        .Where(g => g.Count() > 1)
        .Select(g => g.Key)
        .ToListAsync();

    return source.Where(item => duplicateKeys.Contains(keySelector.Compile()(item)));
}
// 使用示例:
// var duplicateItems = await GetItemsSecureAsync().NonDistinctAsync(item => item.OwnerId);

额外注意点

  • 替换.Result为await:同步调用异步方法(.Result)可能导致死锁,始终使用异步语法保证代码健壮性。
  • 若EF Core版本可升级,后续版本已修复类似分组翻译问题,升级到EF Core 8+可简化写法。

内容的提问来源于stack exchange,提问作者Luk164

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:27:39