C# 联接并更新数据表

C# 联接并更新数据表,c#,asp.net,linq,datatable,C#,Asp.net,Linq,Datatable,我有两个表1和表2,其列的值如下所示: 以下是两个表格: 我想更新表1中的“PaidAmount”。基于两个表中的“InvoiceNo”列进行联接 表1: InvoiceNo Vendor InvoiceValue InvoiceDate PaidAmount --------- ------ ------------- ----------- ---------- 1 AA 15000 01 Dec 20

我有两个表1和表2,其列的值如下所示: 以下是两个表格: 我想更新表1中的“PaidAmount”。基于两个表中的“InvoiceNo”列进行联接

表1:

 InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
 ---------  ------   ------------- -----------      ---------- 
    1        AA        15000       01 Dec 2013         0      
    2        BB        20000       10 Dec 2013         0      
    3        CC        10000       18 Dec 2013         0      
 VoucherNo   Date       InvoiceNo  Amount
 -------   ----------- ----------  ------
   001     01 Nov 2013    1         5000
   002     10 Nov 2013    2         6000
   003     20 Nov 2013    3         7000
   001     02 Nov 2013    1         2000
 InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
 ---------  ------   ------------- -----------      ---------- 
     1        AA        15000       01 Dec 2013        7000      
     2        BB        20000       10 Dec 2013        6000
     3        CC        10000       18 Dec 2013        7000
表2:

 InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
 ---------  ------   ------------- -----------      ---------- 
    1        AA        15000       01 Dec 2013         0      
    2        BB        20000       10 Dec 2013         0      
    3        CC        10000       18 Dec 2013         0      
 VoucherNo   Date       InvoiceNo  Amount
 -------   ----------- ----------  ------
   001     01 Nov 2013    1         5000
   002     10 Nov 2013    2         6000
   003     20 Nov 2013    3         7000
   001     02 Nov 2013    1         2000
 InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
 ---------  ------   ------------- -----------      ---------- 
     1        AA        15000       01 Dec 2013        7000      
     2        BB        20000       10 Dec 2013        6000
     3        CC        10000       18 Dec 2013        7000
我想要的数据表应该是这样的:

Table1.AsEnumerable().Join(Table2.AsEnumerable(),
                      dt1_Row => dt1_Row.ItemArray[0],
                      dt2_Row => dt2_Row.ItemArray[2],
                      dt1_Row, dt2_Row) => new { dt1_Row, dt2_Row }
                      ).ToList()
                   .ForEach(o => o.dt1_Row.SetField(4, o.dt1_Row.ItemArray[4] +  o.dt2_Row.ItemArray[3]));
需要:

 InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
 ---------  ------   ------------- -----------      ---------- 
    1        AA        15000       01 Dec 2013         0      
    2        BB        20000       10 Dec 2013         0      
    3        CC        10000       18 Dec 2013         0      
 VoucherNo   Date       InvoiceNo  Amount
 -------   ----------- ----------  ------
   001     01 Nov 2013    1         5000
   002     10 Nov 2013    2         6000
   003     20 Nov 2013    3         7000
   001     02 Nov 2013    1         2000
 InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
 ---------  ------   ------------- -----------      ---------- 
     1        AA        15000       01 Dec 2013        7000      
     2        BB        20000       10 Dec 2013        6000
     3        CC        10000       18 Dec 2013        7000
如何达到这个效果? 我试过下面的那个

Table1.AsEnumerable().Join(Table2.AsEnumerable(),
                      dt1_Row => dt1_Row.ItemArray[0],
                      dt2_Row => dt2_Row.ItemArray[2],
                      dt1_Row, dt2_Row) => new { dt1_Row, dt2_Row }
                      ).ToList()
                   .ForEach(o => o.dt1_Row.SetField(4, o.dt2_Row.ItemArray[3]));
但结果是

InvoiceNo  Vendor   InvoiceValue  InvoiceDate      PaidAmount 
---------  ------   ------------- -----------      ---------- 
    1        AA        15000       01 Dec 2013        2000      
    2        BB        20000       10 Dec 2013        6000
    3        CC        10000       18 Dec 2013        7000

如何获取所需的表?

看起来您正在迭代结果并覆盖,而不是从其他行添加到预先存在的结果中。您可能希望执行以下操作:

Table1.AsEnumerable().Join(Table2.AsEnumerable(),
                      dt1_Row => dt1_Row.ItemArray[0],
                      dt2_Row => dt2_Row.ItemArray[2],
                      dt1_Row, dt2_Row) => new { dt1_Row, dt2_Row }
                      ).ToList()
                   .ForEach(o => o.dt1_Row.SetField(4, o.dt1_Row.ItemArray[4] +  o.dt2_Row.ItemArray[3]));

您的加入将为您提供多个第1行、第2行夫妇的列表。
因此,您将每对夫妇循环一次,第一次为invoiceNo1,
row1.PaidAmount=5000
,然后继续循环,第二次为
row1.PaidAmount=2000
,因此您的结果是

您希望对第2行的金额值求和,因此加入后,必须按InvoiceValue对数据进行分组,然后执行求和:

foreach(var grp in Table1.AsEnumerable()
      .Join(Table2.AsEnumerable(),
            dt1_Row => dt1_Row.ItemArray[0],
            dt2_Row => dt2_Row.ItemArray[2],
            dt1_Row, dt2_Row) => new { dt1_Row, dt2_Row }
       )
      .GroupBy(o => o.dt1_Row.ItemArray[0]))
{
    var row1 = grp.First().dt1_Row;
    var sum = grp.Sum(t => Convert.ToDecimal(t.dt2_Row.ItemArray[3]));
    row1.SetField(4, sum)
}

为了提高可读性,尽量避免使用ForEach of List,它并不能真正改善代码。

这里有一种方法。您可以使用
GroupBy
创建发票组,使用
ToDictionary
创建有效的
InvoiceNo
PaidAmount
查找。然后您只需要一个循环来更新行:

var invoiceGroups = from r1 in Table1.AsEnumerable()
                    join r2 in Table2.AsEnumerable()
                    on r1.Field<int>("InvoiceNo") equals r2.Field<int>("InvoiceNo")
                    group r2 by r2.Field<int>("InvoiceNo") into InvoiceGroup
                    select InvoiceGroup;
Dictionary<int, int> invoiceSumLookup = invoiceGroups
    .ToDictionary(ig => ig.Key, ig => ig.Sum(r => r.Field<int>("Amount")));
foreach(DataRow row in Table1.Rows)
    row.SetField("PaidAmount", invoiceSumLookup[row.Field<int>("InvoiceNo")]);
var invoiceGroups=来自表1.AsEnumerable()中的r1
将r2加入表2中。AsEnumerable()
r1上的字段(“发票编号”)等于r2上的字段(“发票编号”)
按r2.Field(“InvoiceNo”)将r2分组到InvoiceGroup中
选择发票组;
字典invoiceSumLookup=invoiceGroups
.ToDictionary(ig=>ig.Key,ig=>ig.Sum(r=>r.Field(“金额”));
foreach(表1中的DataRow行。行)
row.SetField(“PaidAmount”,invoiceSumLookup[row.Field(“InvoiceNo”));
请注意,这不会从
表1
中删除重复的
InvoiceNo
行(如果可能且不需要)。它只是按该列对第二个表进行分组,并对所有
Amount
s进行求和


它修改原始表,不需要创建新表。

它给出以下错误:“错误1运算符“+”不能应用于“object”和“object”类型的操作数”。您需要在ItemArray中获取对象的值。我不知道ItemArray中的项的基本类型是什么。您可能需要将其强制转换为适当的类型。它给出错误:无法将类型“object”隐式转换为“decimal”。我已使用从object到int的转换更新了代码。字段Amount的类型是什么?decimal是Amount和paidamount的数据类型。