使用LINQ连接数据表,选择多个列并按多个列进行组合

时间:2018-01-04 11:35:39

标签: c# linq join datatable group-by

我正在使用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)

这些将按supplierID和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

如何获得我想要的结果?

EDIT 2018-01-05

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

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

错误CS1929&#39; EnumerableRowCollection&lt;&gt;&#39;不包含&#39; Concat&#39;的定义和最好的扩展方法重载&#39; Queryable.Concat&lt;&gt;(IQueryable&lt;&gt;,IEnumerable&lt;&gt;)&#39;需要一个类型为“IQueryable&lt;&gt;&#39;

的接收器

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

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

错误是由于table tablessum和table2sum中的字段之间的类型差异造成的。具体而言,字段&#34;供应&#34;和&#34;需求&#34;在比较表中有不同的类型。当我改变了

demand = 0.0

supply = 0.0

编译器找到.Concat -method。

1 个答案:

答案 0 :(得分: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)
             };