使用LINQ连接DataTable,按多列分组求和的问题
解决LINQ连接DataTable分组求和及无匹配项填充的问题
从你的描述和代码来看,主要存在三个核心问题:内连接导致丢失无匹配记录、分组逻辑混淆了供需双方的供应商ID,以及你遇到的CS1929类型不匹配错误。下面一步步拆解解决:
错误原因分析
- 内连接的局限性:你使用的
join是内连接,只会保留两个表中propertyID匹配的记录,那些没有对应供应或需求的供应商+属性组组合会被直接丢弃,自然无法得到无匹配时的0值。 - 分组逻辑偏差:你的分组键用的是
supplyItems的supplierID(供应方供应商),但demandItems里的supplierID是需求方的供应商,这会导致需求总和被错误关联到供应方的供应商下,计算结果必然不符合预期。 - Concat的类型要求:匿名类型执行
Concat时,要求两个集合的匿名类型字段名称、类型、顺序完全一致,之前的CS1929错误就是因为demand和supply的类型不匹配,改成0.0(统一为double类型)就能解决。
正确解决方案
我们需要先分别对两个表做预聚合,再合并所有可能的分组键,最后通过分组求和自动填充无匹配项的0值,具体步骤如下:
1. 预聚合需求数据
先对Demands表按需求方supplierId和propertyGroupID分组,计算需求总和:
var demandGroups = from d in table1.AsEnumerable() group d by new { SupplierId = d.Field<int>("supplierId"), PropertyGroupId = d.Field<int>("propertyGroupID") } into g select new { g.Key.SupplierId, g.Key.PropertyGroupId, SumDemand = g.Sum(x => x.Field<double>("demand")), SumSupply = 0.0 // 占位字段,保证和供应集合的匿名类型结构一致 };
2. 预聚合供应数据
供应表没有propertyGroupID,需要先关联Demands表拿到对应的属性组,再按供应方supplierId和属性组分组计算供应总和:
var supplyGroups = from s in table2.AsEnumerable() join d in table1.AsEnumerable() on s.Field<int>("propertyID") equals d.Field<int>("propertyID") group s by new { SupplierId = s.Field<int>("supplierId"), PropertyGroupId = d.Field<int>("propertyGroupID") } into g select new { g.Key.SupplierId, g.Key.PropertyGroupId, SumDemand = 0.0, // 占位字段,保证和需求集合的匿名类型结构一致 SumSupply = g.Sum(x => x.Field<double>("supply")) };
3. 合并分组并计算最终结果
将两个预聚合的结果合并,再按SupplierId和PropertyGroupId分组求和,自动填充无匹配项的0值:
var result = from item in demandGroups.Concat(supplyGroups) group item by new { item.SupplierId, item.PropertyGroupId } into g select new { SupplierID = g.Key.SupplierId, PropertyGroupId = g.Key.PropertyGroupId, SumOfSupply = g.Sum(x => x.SumSupply), SumOfDemand = g.Sum(x => x.SumDemand) };
补充说明
- 这里的
Concat能正常执行,是因为两个匿名类型的字段(SupplierId、PropertyGroupId、SumDemand、SumSupply)名称和类型完全一致,解决了你之前遇到的CS1929错误。 - 如果某个供应商+属性组只有需求没有供应,
SumOfSupply会自动为0;反之SumOfDemand会为0,完全符合你对比供需的需求。 - 注意字段类型匹配:确保
Field<T>中的类型和DataTable实际字段类型一致,避免不必要的类型转换错误。
内容的提问来源于stack exchange,提问作者Markku Rintala
相关产品推荐
相关产品推荐

