如何在EF Core单次调用中同时获取数据行数与列总和?
可以,通过单次EF Core查询同时获取总和与行数
你完全可以将两次数据库调用合并为一次,通过LINQ的聚合投影实现,减少数据库往返次数,提升性能。
首先修正你原代码中的一处笔误:第二个查询的x.Date = request.StartDate应该是x.Date >= request.StartDate,否则会筛选错误的时间范围。
优化后的代码示例如下:
var stats = await dbContext.Transaction .Where(x => x.UserName == request.UserName && x.Date >= request.StartDate && x.Date <= request.EndDate) .GroupBy(_ => 1) // 将所有符合条件的记录归为一组 .Select(g => new { TotalCost = g.Sum(x => x.Amount), TotalNumber = g.Count() }) .FirstOrDefaultAsync(); TotalCostResponse result = new TotalCostResponse { TotalCost = stats?.TotalCost ?? 0, // 处理无匹配数据的情况 TotalNumber = stats?.TotalNumber ?? 0 };
原理说明
EF Core会将这段LINQ代码翻译为一条包含SUM(Amount)和COUNT(*)的SQL语句,仅向数据库发起一次请求,直接返回聚合后的结果,避免了两次查询的额外开销。
如果不想使用GroupBy,也可以直接通过Select结合EF内置函数(部分EF Core版本支持),不过GroupBy的写法兼容性更好:
var stats = await dbContext.Transaction .Where(x => x.UserName == request.UserName && x.Date >= request.StartDate && x.Date <= request.EndDate) .Select(_ => new { TotalCost = EF.Functions.Sum(dbContext.Transaction.Where(t => t.UserName == request.UserName && t.Date >= request.StartDate && t.Date <= request.EndDate).Select(t => t.Amount)), TotalNumber = EF.Functions.Count(dbContext.Transaction.Where(t => t.UserName == request.UserName && t.Date >= request.StartDate && t.Date <= request.EndDate).Select(t => t.Id)) }) .FirstOrDefaultAsync();
内容的提问来源于stack exchange,提问作者samy yasser
相关产品推荐
相关产品推荐

