【问题标题】:Is there a way to merge two DataTables and only preserve changes for specific columns?有没有办法合并两个数据表并只保留特定列的更改?
【发布时间】: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


    【解决方案1】:

    好吧,看来解决方案对我来说很容易想到。

    我只是换了桌子,反过来做了DataTable.Merge()。所以解决方案是:

    ShippingTable.Merge(BillingTable);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-11
      • 2020-10-20
      • 1970-01-01
      • 2020-06-17
      • 2023-02-06
      • 2022-12-01
      • 2021-01-15
      • 2014-10-13
      相关资源
      最近更新 更多