C# 联接并更新数据表
我有两个表1和表2,其列的值如下所示: 以下是两个表格: 我想更新表1中的“PaidAmount”。基于两个表中的“InvoiceNo”列进行联接 表1: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
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的数据类型。