ASP.NET Core中HttpGet接口用GroupBy去重时报InvalidOperationException如何解决
报错原因
你遇到的异常是EF Core 3.x及更高版本的默认限制导致:你写的GroupBy后取分组第一条的LINQ逻辑无法被EF Core转换为合法的SQL语句,而该版本之后EF Core默认禁止隐式的客户端求值操作,因此直接抛出运行时异常。
另外你现有写法中OrderBy(x => x.ClientId)的排序逻辑没有实际意义,因为分组的Key就是ClientId,同一分组内所有订单的ClientId完全相同,你可以改为按订单ID或下单时间排序,来明确取每个客户的第一条订单规则。
解决方案
方案1(推荐,EF Core 6+ 版本适用)
EF Core 6开始内置了DistinctBy方法,你要实现的按ClientId去重的需求可以直接用该方法实现,并且可以被EF Core正常翻译成SQL,执行效率最高:
[HttpGet] public async Task<ActionResult<IEnumerable<Order>>> GetOrders() { return await _database.Orders .Include(c => c.Client) .DistinctBy(c => c.ClientId) .ToListAsync(); }
方案2(低版本EF Core适用)
如果你用的是EF Core 5及更低版本,可以先把匹配的订单数据加载到内存后,再执行分组去重逻辑,该方案只适合订单数据量较小的场景,若订单表数据量较大,一次性加载全量数据可能引发性能问题:
[HttpGet] public async Task<ActionResult<IEnumerable<Order>>> GetOrders() { // 先执行SQL查询把订单及关联的客户数据加载到内存 var orders = await _database.Orders .Include(c => c.Client) .ToListAsync(); // 在内存中执行分组去重逻辑 return orders .GroupBy(c => c.ClientId) .Select(c => c.OrderBy(x => x.Id).FirstOrDefault()) .ToList(); }
内容的提问来源于stack exchange,提问作者Sam Pineda
相关产品推荐
相关产品推荐

