C# Entity Framework中使用Lambda实现含多Sum()运算的SQL查询
EF Lambda 实现多Sum聚合查询
你可以通过GroupBy按常量分组的方式,将两个Sum运算合并到同一次数据库查询中,生成的SQL和你提供的原生语句逻辑完全一致:
public double GetDriverAvgRating(string id) { var driver = _context.CustomerRating .AsQueryable() .Where(d => d.DriverId == id); var avgDriverRating = driver .GroupBy(_ => 1) // 所有符合条件的记录归为同一组 .Select(g => g.Sum(r => r.Rating * r.Rating) * 1.0 / g.Sum(r => r.Rating)) .FirstOrDefault(); // 可选:处理无评分时的默认值,无数据时FirstOrDefault会返回0,可根据业务调整 return avgDriverRating; }
边界场景兼容处理
如果需要兼容司机无评分、总分和为0的场景,避免除以0报错,可以调整为如下写法:
public double GetDriverAvgRating(string id) { var driver = _context.CustomerRating .AsQueryable() .Where(d => d.DriverId == id); var aggResult = driver .GroupBy(_ => 1) .Select(g => new { SumRatingSquare = g.Sum(r => r.Rating * r.Rating), SumRating = g.Sum(r => r.Rating) }) .FirstOrDefault(); // 无匹配记录/总分为0时返回默认值0,可根据业务需求修改 if (aggResult == null || aggResult.SumRating == 0) return 0; return (double)aggResult.SumRatingSquare / aggResult.SumRating; }
不推荐写法
不建议分开调用两次Sum,会发起两次数据库查询,性能更低:
// 不推荐:两次数据库请求 var sumSquare = driver.Sum(r => r.Rating * r.Rating); var sumRating = driver.Sum(r => r.Rating); var avgDriverRating = sumRating == 0 ? 0 : (double)sumSquare / sumRating;
内容的提问来源于stack exchange,提问作者M.N. Waleedh
相关产品推荐
相关产品推荐

