EF Core如何进行聚合查询 EF Core Sum, Avg, Count聚合方法

EF Core聚合查询将计算下推至数据库执行,需用Count()、Sum()、Avg()等方法生成对应SQL;分组聚合用GroupBy+Select保持IQueryable;注意null处理及类型匹配,避免.ToList()导致内存计算。

EF Core 的聚合查询本质是把计算逻辑下推到数据库执行,而不是在内存里遍历。用对方法,才能既准确又高效。

常用聚合方法怎么写

直接调用 Count()Sum()Avg() 等扩展方法,它们会生成 SQL 的对应聚合函数:

  • Count():统计行数,context.Orders.Count()SELECT COUNT(*) FROM Orders
  • Count(x => x.Status == "Shipped"):带条件计数,生成 COUNT(CASE WHEN ... THEN 1 END)
  • Sum(x => x.Amount):只支持数值类型字段,null 值自动忽略
  • Avg(x => x.Rating):同理,字段为 null 的记录不参与计算
  • Max(x => x.CreatedAt)Min(x => x.Price):支持日期、数字、字符串(按字典序)

分组后聚合更实用

单表聚合往往不够,多数业务需要“按某维度分组再算总数/平均值”。EF Core 支持链式 GroupBy + Select

  • context.Orders.GroupBy(o => o.CustomerId).Select(g => new { Id = g.Key, Total = g.Sum(o => o.Amount) })
  • 结果是 IQueryable,仍走数据库,不会把全部订单拉到内存
  • 可嵌套多个聚合:g.Average(o => o.Quantity)g.Count() 同时用

注意 null 和类型陷阱

聚合行为和数据库一致,但容易踩坑:

  • Count(x => x.Name) 统计的是 Name IS NOT NULL 的行数,不是总行数
  • Sum()Avg() 遇到非数值类型字段(比如 string),运行时报错或返回 0(取决于 provider)
  • Max()/Min() 对字符串字段,按字母顺序比较,不是按长度
  • 想统计所有行(含 null),用 Count() 不带参数;想统计某列非空行,才传表达式

避免常见性能错误

聚合必须保持在服务端执行,否则失去意义:

  • ❌ 错误:先 .ToList().Sum() → 全量查出再内存计算
  • ✅ 正确:所有聚合操作前不触发枚举,保持 IQueryable 状态
  • 调试时可用 context.Orders.ToQueryString()(EF Core 7+)看生成的 SQL

基本上就这些。写对表达式,看清字段类型,让数据库干活,别自己搬数据。