You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LINQ连接DataTable,按多列分组求和的问题

解决LINQ连接DataTable分组求和及无匹配项填充的问题

从你的描述和代码来看,主要存在三个核心问题:内连接导致丢失无匹配记录、分组逻辑混淆了供需双方的供应商ID,以及你遇到的CS1929类型不匹配错误。下面一步步拆解解决:

错误原因分析

  1. 内连接的局限性:你使用的join是内连接,只会保留两个表中propertyID匹配的记录,那些没有对应供应或需求的供应商+属性组组合会被直接丢弃,自然无法得到无匹配时的0值。
  2. 分组逻辑偏差:你的分组键用的是supplyItems的supplierID(供应方供应商),但demandItems里的supplierID是需求方的供应商,这会导致需求总和被错误关联到供应方的供应商下,计算结果必然不符合预期。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:13:11