【发布时间】:2019-04-08 15:15:02
【问题描述】:
我有以下两个表格,它们是从 Excel 文件导入到我的 Windows 窗体应用程序中的。这些文件是自动创建的,很遗憾,无法更改它们。我简化了下面的所有示例。实际上,这些表有 40 多列,每列超过 10 万行。
第一个表包含客户账单信息,其中 customer 是客户编号,我将其用作主键。
BillingTable
Customer(PK) Name Address Type
------------ ------------- ---------- -----------
1 Customer 1 Address 1 Billing
2 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
第二个表包含客户发货信息,并有另一个客户编号。 “合作伙伴”列引用了结算信息:
ShippingTable
Customer Name Address Type Partner(PK)
--------- ----------- -------------- ---------- ------------
4 Customer 1 Sh.Address 1 Shipping 1
5 Customer 2 Sh.Address 2 Shipping 2
6 Customer 4 Sh.Address 4 Shipping 6
如您所见,账单信息表中有一些条目未在运输信息表中引用。客户也有运输信息但没有账单信息。在这种情况下,合作伙伴列包含运输信息表中的客户编号。
我必须将两个表合并到以下:
ResultTable
Customer(PK) Shipping Name Address Type
------------- ----------- ------------ ------------ ----------
1 4 Customer 1 Address 1 Billing
2 5 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
6 6 Customer 4 Sh.Address 4 Shipping
所以我需要一张表,其中仅将运输客户编号添加到帐单表中(如果有的话)。如果没有,运输栏可以保持空白。如果有运输信息但没有账单信息,我想从 ShippingTable 中获取整行。
当简单地使用DataTable.Merge() 方法(如BillingTable.Merge(ShippingTable))时,帐单表的地址和类型列将被运输信息覆盖。像BillingTable.Merge(ShippingTable, true) 这样将preserveChanges 设置为true 时,它不会将发货客户编号合并到BillingTable 中,而只是将额外的发货客户信息添加到表中。
我还尝试“手动”获取每行的运输编号,方法是遍历它们并使用 Linq 获取所需的运输信息。但由于我正在处理大量行,这需要非常非常长的时间。
接下来我尝试在合并之前从 ShippingTable 中删除地址和类型列。但在这种情况下,我当然会丢失没有账单信息的客户的信息。
所以总结一下,这是我迄今为止尝试过的:
BillingTable.Merge(ShippingTable); // Billing info is overwritten
BillingTable.Merge(ShippingTable, true); // Does not merge shipping number
// Loop through each row, takes very long
foreach(DataRow row in BillingTable.Rows) {
row["Shipping"] = ShippingTable.Rows.Cast<DataRow>()
.Where(shRow => shRow["Partner"].ToString() == row["Customer"])
.First()
.Field<string>("Customer");
}
// Delete Address and Type columns before merging
// Does not include address and type information for shipping only entries
ShippingTable.Columns.Remove("Address");
ShippingTable.Columns.Remove("Type");
BillingTable.Merge(ShippingTable);
结果如下:
使用 BillingTable.Merge(ShippingTable)
Customer(PK) Shipping Name Address Type
------------- ----------- ------------ ------------- ---------
1 4 Customer 1 Sh.Address 1 Shipping
2 5 Customer 2 Sh.Address 2 Shipping
3 Customer 3 Address 3 Billing
6 6 Customer 4 Sh.Address 4 Shipping
With BillingTable.Merge(ShippingTable, true)
Customer(PK) Shipping Name Address Type
------------- ------------ ------------ ------------- ---------
1 Customer 1 Address 1 Billing
2 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
6 6 Customer 4 Sh.Address 4 Shipping
在合并前从 ShippingTable 中删除“地址”和“类型”列时:
Customer(PK) Shipping Name Address Type
------------- ----------- ------------ ------------ ----------
1 4 Customer 1 Address 1 Billing
2 5 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
6 6
因此,要么有一种方法可以合并我目前无法找到的表,要么我将不得不以另一种方式进行。我曾考虑在从 Excel 文件中获取表时使用 SQL 加入表,或者使用 Linq 而不是 DataTable.Merge() 加入表,但我无法让任何一种方式正常工作。
有人可以帮忙吗?
(对不起,描述太长了)
【问题讨论】:
标签: c# winforms merge datatable