如何在LINQ中计算累计求和?SQL窗口函数转LINQ实操问题求助
解决方案
你要实现的SQL核心是左关联Natures表后按idNature排序,计算montant的累计值,分两种适配场景提供写法:
场景1:EF Core 7.0及以上版本(支持原生窗口函数翻译)
直接通过EF Core内置的窗口函数扩展实现,可直接翻译为你给出的原生SQL,查询在数据库端执行性能更好:
var result = await context.BalanceSorties .GroupJoin( context.Natures, bs => bs.idNature, n => n.idNature, (bs, nGroup) => new { bs, n = nGroup.FirstOrDefault() } ) .OrderBy(x => x.bs.idNature) .Select(x => new { x.bs.idBalancesortie, x.bs.datesortie, x.bs.c_num_debut, x.bs.c_num_fin, x.bs.nombredetickets, Quotite = x.n != null ? x.n.quotite : (int?)null, // 左连空值处理,类型和quotite字段保持一致即可 x.bs.montant, Cumul = EF.Functions.SumOver( x.bs.montant, orderBy: o => o.OrderBy(item => item.bs.idNature), rows: (0, null) // 对应ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), x.bs.idNature }) .ToListAsync();
场景2:低版本EF Core / EF6(不支持窗口函数翻译)
先查询出基础关联数据,在内存中计算累计值,兼容所有版本:
// 第一步:先查询基础关联数据,在数据库端执行 var baseData = await context.BalanceSorties .GroupJoin( context.Natures, bs => bs.idNature, n => n.idNature, (bs, nGroup) => new { bs, n = nGroup.FirstOrDefault() } ) .OrderBy(x => x.bs.idNature) .Select(x => new { x.bs.idBalancesortie, x.bs.datesortie, x.bs.c_num_debut, x.bs.c_num_fin, x.bs.nombredetickets, Quotite = x.n != null ? x.n.quotite : (int?)null, x.bs.montant, x.bs.idNature }) .ToListAsync(); // 第二步:内存中计算累计值 decimal cumul = 0; var result = baseData.Select(x => new { x.idBalancesortie, x.datesortie, x.c_num_debut, x.c_num_fin, x.nombredetickets, x.Quotite, x.montant, Cumul = cumul += x.montant, x.idNature }).ToList();
内容的提问来源于stack exchange,提问作者Mousse
相关产品推荐
相关产品推荐

