【问题标题】:Check whether two datatables contain the same data检查两个数据表是否包含相同的数据
【发布时间】:2020-12-02 10:44:33
【问题描述】:

我有两个具有相同结构的数据表。但其中的数据可能不同。

我需要一种快速的方法来检查数据是相同还是不同。我不需要知道有什么不同,因为其中一个是“新”数据表,另一个是“旧”数据表。如果存在差异,那么用户将不得不决定他想要新的还是旧的。

比较它们的好方法是什么?

我只知道逐个检查并比较它们,但必须有更快、更智能的方法。

【问题讨论】:

    标签: vb.net datatable compare


    【解决方案1】:

    当然你需要检查每个单元格,但你可以使用DataRowComparer.Equals

    Public Shared Function AreTablesEqual(t1 As DataTable, t2 As DataTable) As Boolean
        If t1 Is Nothing AndAlso t2 Is Nothing Then Return True
        If t1 Is Nothing OrElse t2 Is Nothing Then Return False
        If t1.Columns.Count <> t2.Columns.Count Then Return False
        If t1.Rows.Count <> t2.Rows.Count Then Return False
    
        For i As Int32 = 0 To t1.Rows.Count - 1
            If Not DataRowComparer.Default.Equals(t1.Rows(i), t2.Rows(i)) Then Return False
        Next
    
        Return True
    End Function
    

    如果有人搜索 C# 版本:

    public static bool AreTablesEqual(DataTable t1, DataTable t2)
    {
        if (t1 == null && t2 == null) return true;
        if (t1 == null || t2 == null) return false;
        if (t1.Columns.Count != t2.Columns.Count || t1.Rows.Count != t2.Rows.Count) return false;
    
        for (int i = 0; i < t1.Rows.Count; i++)
        {
            if (!DataRowComparer.Default.Equals(t1.Rows[i], t2.Rows[i])) return false;
        }
    
        return true;
    }
    

    【讨论】:

    • 谢谢!我认为可能有一个散列函数可以让我生成 teh 变量的散列,然后我可以通过检查散列快速比较它们.. 感谢您的解决方案
    【解决方案2】:

    如果您将这两个表视为两组 DataRows(与接受的答案相反,顺序无关紧要),那么您可以使用 Enumerable.Except Method 使用 DataRowComparer.Default 作为相等比较器来确定不同的 DataRows .然后使用Enumerable.Any Method 确定是否发现任何差异。

    Private Shared Function TableRowsAreTheSame(table1 As DataTable, table2 As DataTable) As Boolean
      Dim bothNull As Boolean = table1 Is Nothing AndAlso table2 Is Nothing
      Dim bothNotNull As Boolean = table1 IsNot Nothing AndAlso table2 IsNot Nothing
    
    
      Dim equalColumnAndRowCounts As Func(Of Boolean) = Function() (table1.Rows.Count = table2.Rows.Count) AndAlso (table1.Columns.Count = table2.Columns.Count)
      Dim equalFieldTypes As Func(Of Boolean) = Function()
                                                  Dim typeAreEqual As Boolean
                                                  For index As Int32 = 0 To table1.Columns.Count - 1
                                                    typeAreEqual = table1.Columns(index).DataType.Equals(table2.Columns(index).DataType)
                                                    If Not typeAreEqual Then Exit For
                                                  Next
                                                  Return typeAreEqual
                                                End Function
    
    
      Dim equalFieldValues As Func(Of Boolean) = Function()
                                                    ' get rows in table1 that are Not in table2
                                                    Dim differringRows As IEnumerable(Of DataRow) = Enumerable.Except(table1?.AsEnumerable(), table2?.AsEnumerable(), DataRowComparer.Default)
                                                    Return (Not differringRows.Any)
                                                  End Function
    
    
    
      Return bothNull OrElse
          (bothNotNull AndAlso equalColumnAndRowCounts() AndAlso equalFieldTypes() AndAlso equalFieldValues())
    
    
    End Function
    

    【讨论】:

    • 你应该总是更喜欢Not differringRows.Any(),而不是differringRows.Count() = 0。使用前者,您必须计算 所有 不同的行,而后者只检查是否有一个,这是您真正想知道的。
    • @TimSchmelter,谢谢。这完全让我忘记了。我将其纳入答案中。
    • 这就是为什么我不喜欢方法的括号在 VB.NET 中是可选的。很容易将它与 ICollectionCount 属性混淆,即 O(1)。但即使使用数组/列表,我也更喜欢Any,因为它更好地表达了意图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多