【问题标题】:Join datatables with LINQ, select multiple columns and sums with group by multiple columns使用 LINQ 连接数据表,选择多列并通过多列分组求和
【发布时间】:2018-06-14 03:11:29
【问题描述】:

我正在使用 LINQ 连接两个数据表并尝试从两个表中选择数据,包括按两列分组的一列的总和。数据结构看起来是这样的。

table1 (Demands)
  propertyID
  propertyGroupID
  supplierID
  demand

propertyID  |propertyGroupID    |supplierId |demand |ContractId
13          |3                  |3          |2      |1
22          |4                  |3          |1      |1
21          |5                  |3          |12     |1
15          |5                  |3          |3      |1
16          |7                  |3          |16     |1
23          |5                  |3          |5      |1


table2 (Supplies)
  supplierID
  propertyID
  supply

supplierId  |propertyID |supply
4           |23         |2764
1           |22         |3521
1           |16         |2533
11          |23         |876
4           |21         |5668

我希望得到结果

supplierID
propertyGroupID
sum(supply)
sum(demand)

这些将按供应商ID 和propertyGroupID 分组。因此,最后我想将实际供应与每个供应商和物业组的需求进行比较。

到目前为止我所做的是

var result = from demandItems in table1.AsEnumerable()
             join supplyItems in table2.AsEnumerable() on
Convert.ToInt16(demandItems["propertyID"]) equals 
Convert.ToInt16(supplyItems["propertyID"])
             group new
             {
                demandItems,
                supplyItems
            }
            by new
            {
                Supplier = supplyItems.Field<string>("supplierID"),
                PropertyGroup = demandItems.Field<int>("propertyGroupID")
            }
            into groupDt
             select new
             {
                SupplierID = groupDt.Key.Supplier,
                PropertyGroupId = groupDt.Key.PropertyGroup,
                SumOfSupply = groupDt.Sum(g => g.supplyItems.Field<double>("supply")),
            SumOfDemand = groupDt.Sum(g => g.demandItems.Field<double>("demand"))
        };

这很好用,我得到了按不同供应商和属性组分组的正确供应总和。但是,需求的总和是不正确的。

SupplierID  |PropertyGroupID    |SumOfSupply    |SumOfDemand
4           |5                  |8432           |17
1           |4                  |3521           |1
1           |7                  |2533           |16
11          |5                  |876            |5

如您所见,table1 只有一个供应商 (ID=3)。正确的结果数据应该是

SupplierID  |PropertyGroupID    |SumOfSupply    |SumOfDemand
4           |5                  |8432           |0
1           |4                  |3521           |0
1           |7                  |2533           |0
11          |5                  |876            |0
3           |3                  |0              |2
3           |4                  |0              |1              
3           |5                  |0              |20
3           |7                  |0              |16

如何得到我想要的结果?

编辑 2018-01-05

我正在使用 NetMage 的解决方案来解决我的问题。但是,我收到来自

的错误消息
var result = from d in table1sum.Concat(table2sum)...

错误 CS1929 'EnumerableRowCollection' 不包含 'Concat' 的定义,并且最佳扩展方法重载 'Queryable.Concat(IQueryable, IEnumerable)' 需要类型为 'IQueryable 的接收器'

这可能是因为我的原始表实际上是从数据库中读取的吗?

DataTable table1 = DemandDataSet.Tables[0];
DataTable table2 = SupplyDataSet.Tables[0];

例如,我必须使用符号

var table1sum = table1.AsEnumerable().Select(d => new
            { propertyGroupID = (int)d["propertyGroupID"],
            supplierId = (int)d["supplierId"],
            demand = (double)d["demand"],
            supply = 0 });

编辑 2 2018-01-05

该错误是由于表 table1sum 和 table2sum 中的字段之间的类型差异造成的。具体来说,“供应”和“需求”字段在比较表中具有不同的类型。当我改变了

demand = 0.0

supply = 0.0

编译器找到 .Concat -方法。

【问题讨论】:

  • 你为什么加入propertyID?我认为您需要一些示例数据来显示当table1table2 中也有SupplierID 时会发生什么。
  • PropertyID 是到 pr​​opertyGroup 的连接。 Table2 没有关于 propertyGroup 的信息。

标签: c# linq join datatable group-by


【解决方案1】:

您的数据表未标准化,我认为这是导致您的问题的原因。您真的不想合并供需表。

首先,将需求表汇总为结果所需的信息:

var table1sum = table1.AsEnumerable().Select(d => new { d.propertyGroupID, d.supplierId, d.demand, supply = 0 });

其次,将供应表汇总为结果所需的信息,使用需求表得到需要的propertyGroupID

var table2sum = from supplyItem in table2.AsEnumerable()
                join demandItem in table1.AsEnumerable() on supplyItem.propertyID equals demandItem.propertyID
                select new {
                    demandItem.propertyGroupID,
                    supplyItem.supplierId,
                    demand = 0,
                    supplyItem.supply
                };

现在您可以结合摘要和分组来获得所需的结果:

var result = from d in table1sum.Concat(table2sum)
             group d by new { d.supplierId, d.propertyGroupID } into dg
             select new {
                 SupplierID = dg.Key.supplierId,
                 PropertyGroupId = dg.Key.propertyGroupID,
                 SumOfSupply = dg.Sum(g => g.supply),
                 SumOfDemand = dg.Sum(g => g.demand)
             };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2022-11-12
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多