LINQ分组聚合需求:按Vendor、Type分组,合并Month并求和NumberInvoice
正确实现Invoice数据分组与聚合的LINQ代码
需求说明
需要对Invoice列表执行以下处理:
- 先按
Vendor字段分组,再按Type字段分组(最终分组键为Vendor + Type的组合) - 将每组内的
Month字段值拼接为逗号分隔的字符串 - 对每组内的
NumberInvoice字段求和
原代码的问题
原LINQ代码存在两处关键错误:
- 分组键错误:将
NumberInvoice加入分组键,导致同Vendor+Type的记录被不必要拆分,无法实现正确的聚合逻辑 - 属性与语法错误:
- 初始化对象时错误使用小写
month(原类属性为Month且类型为int,无法存储字符串) - 求和逻辑错误:试图对单个分组键的
NumberInvoice值求和,而非遍历分组内所有记录计算总和
- 初始化对象时错误使用小写
正确实现方案
由于原Invoice类的Month属性为int类型,无法存储拼接后的字符串,推荐以下两种实现方式:
方案1:使用自定义DTO类
先定义用于承载结果的DTO类:
public class InvoiceSummary { public string Vendor { get; set; } public string Type { get; set; } public string MonthList { get; set; } public int TotalNumberInvoice { get; set; } }
再编写LINQ处理代码:
var result = InputData .GroupBy(x => new { x.Vendor, x.Type }) // 仅按Vendor和Type作为分组键 .Select(g => new InvoiceSummary { Vendor = g.Key.Vendor, Type = g.Key.Type, MonthList = string.Join(",", g.Select(item => item.Month)), // 拼接组内所有Month值 TotalNumberInvoice = g.Sum(item => item.NumberInvoice) // 求和组内NumberInvoice }) .ToList();
方案2:使用匿名类型(无需额外定义类)
如果不需要后续复用结果类型,可直接使用匿名类型简化代码:
var result = InputData .GroupBy(x => new { x.Vendor, x.Type }) .Select(g => new { g.Key.Vendor, g.Key.Type, MonthList = string.Join(",", g.Select(item => item.Month)), TotalNumberInvoice = g.Sum(item => item.NumberInvoice) }) .ToList();
结果示例
基于输入数据,最终处理结果如下:
- Microsoft + PC:MonthList为
"1,2,1,2",TotalNumberInvoice为60 - Microsoft + Surface:MonthList为
"1,1",TotalNumberInvoice为40 - IBM + Network:MonthList为
"5",TotalNumberInvoice为50 - IBM + Graphic Card:MonthList为
"6",TotalNumberInvoice为60
内容的提问来源于stack exchange,提问作者MedAmin
相关产品推荐
相关产品推荐

