如何比较两个 DataTable 并返回差异?

Posted

技术标签:

【中文标题】如何比较两个 DataTable 并返回差异?【英文标题】:How to compare two DataTable and return the diffrence? 【发布时间】:2017-02-09 10:04:03 【问题描述】:

假设我有两个 DataTable dt1 和 dt2,我将行添加到 dt1 并执行 AcceptChanges,然后 dt2 = dt1.Copy 并继续将行添加到 dt2

示例1:-

    dt1                    dt2
    ---------------        ---------------  
    | item  | qty |        | item  | qty |
    ---------------        ---------------
    | Apple |  1  |        | Apple |  1  |
    | Orange|  1  |        | Orange|  1  |
    ---------------        | Banana|  2  |
                           ---------------

Dim dt_compare as DataTable = dt2.GetChanges()

    dt_compare                  
    ---------------       
    | item  | qty |        
    ---------------       
    | Banana|  2  |
    ---------------

上面的结果是我得到的,也是我想要的,但是请看Example2

示例2:-

    dt1                    dt2
    ---------------        ---------------  
    | item  | qty |        | item  | qty |
    ---------------        ---------------
    | Apple |  1  |        | Apple |  1  |
    | Orange|  1  |        | Orange|  10 |
    ---------------        ---------------

Dim dt_compare as DataTable = dt2.GetChanges()

    dt_compare                  
    ---------------       
    | item  | qty |        
    ---------------       
    | Orange|  10 |
    ---------------

如果我只是更改值,当我使用 GetChanges() 时它会返回相同的值。我怎样才能得到结果 9 而不是 10?

【问题讨论】:

您要的是数量上的差异?即 dt2.qty - dt2.qty?你必须自己做。 GetChanges 查找数据中的绝对变化。它说“有区别”,然后报告是/否,并列出更改。它不知道您想对该数据执行什么数学运算 - 毕竟,更改甚至发生在数字字段上只是偶然的。然后,可能有许多不同的可能计算要做,它怎么知道你需要什么?但它给了你机会 - 现在你知道有区别,你可以自己计算以适应自己。 【参考方案1】:

您可以使用RowVersion 来实现您想要的。基本上,您可以检查更改是否是修改,在这种情况下,从原始值中减去当前值。会是这样的:

Dim dat1 As DataTable = New DataTable()
dat1.Columns.Add("item")
dat1.Columns.Add("qty")


dat1.Rows.Add(New Object() "Apple", 1)
dat1.Rows.Add(New Object() "Orange", 1)

dat1.AcceptChanges()
dat1.Rows.Add(New Object() "Banana", 2)
dat1.Rows(1)("qty") = 10

Dim dtChanges As DataTable = dat1.GetChanges()
For Each dr As DataRow In dtChanges.Rows
    If dr.RowState = DataRowState.Modified Then
        dr("qty") = Convert.ToInt16(dr("qty", DataRowVersion.Current)) - Convert.ToInt16(dr("qty", DataRowVersion.Original))

    End If
Next

使用 Linq 的替代方法:

Dim modified = dat1.GetChanges() _ 
                   .AsEnumerable() _ 
                   .Where(Function(x) x.RowState = DataRowState.Modified) _
                   .Select(Function(x) New With 
                     .Key = x("item"),
                     .Value = Convert.ToInt16(x("qty", DataRowVersion.Current)) - Convert.ToInt16(x("qty", DataRowVersion.Original))) _
                   .ToList()

【讨论】:

以上是关于如何比较两个 DataTable 并返回差异?的主要内容,如果未能解决你的问题,请参考以下文章

Lodash / javascript:比较两个集合并返回差异[重复]

比较两个数据帧并根据第一个df返回差异[重复]

比较两个 API 调用的结果并在 MEAN 应用程序中返回它们的差异

比较两个DataTable的差集

C# 两个datatable中的数据快速比较返回交集或差集

如何在行级别上比较两个海量 Spark 数据帧并打印差异