2011-09-05 120 views

回答

8

我不知道任何內置的架構在比較DataTables的方式中,並且沒有定義完整的規範(and you always should),可能我會錯過某些您關心的案例。

認爲下列情況管理比較兩個數據表,並確定以下各項爲真

  • 是數據列的數量在這兩個數據表相同
  • 在第一個DataTable的每一數據列呢一列中的其他表也是同一類型不分順序

它使用擴展方法和實現的IEqualityComparer使COMPAR存在ISON。

測試用例

class Program 
    { 
     static void Main(string[] args) 
     { 

      DataTable dt1 = new DataTable(); 
      dt1.Columns.Add(columnName: "a", type: Type.GetType("System.String")); 
      dt1.Columns.Add(columnName: "b", type: Type.GetType("System.Int32")); 

      DataTable dt2 = new DataTable(); 
      dt2.Columns.Add(columnName: "a", type: Type.GetType("System.Int32")); 
      dt2.Columns.Add(columnName: "b", type: Type.GetType("System.String")); 

      DataTable dt3 = new DataTable(); 
      dt3.Columns.Add(columnName: "a", type: Type.GetType("System.String")); 
      dt3.Columns.Add(columnName: "b", type: Type.GetType("System.Int32")); 
      dt3.Columns.Add(columnName: "c", type: Type.GetType("System.Int32")); 


      DataTable dt4 = new DataTable(); 
      dt4.Columns.Add(columnName: "b", type: Type.GetType("System.Int32")); 
      dt4.Columns.Add(columnName: "a", type: Type.GetType("System.String")); 


      DataTable dt5 = new DataTable(); 
      dt5.Columns.Add(columnName: "a", type: Type.GetType("System.String")); 
      dt5.Columns.Add(columnName: "b", type: Type.GetType("System.Int32")); 


     Console.WriteLine("dt1.SchemaEquals(dt1) | {0}", dt1.SchemaEquals(dt1)); 
     Console.WriteLine("dt1.SchemaEquals(dt2) | {0}", dt1.SchemaEquals(dt2)); 
     Console.WriteLine("dt1.SchemaEquals(dt3) | {0}", dt1.SchemaEquals(dt3)); 
     Console.WriteLine("dt1.SchemaEquals(dt4) | {0}", dt1.SchemaEquals(dt4)); 
     Console.WriteLine("dt1.SchemaEquals(dt5) | {0}", dt1.SchemaEquals(dt5)); 

      if (System.Diagnostics.Debugger.IsAttached) 
      { 
       Console.ReadLine(); 
      } 


     } 


    } 

擴展方法

public static class DataTableSchemaCompare 
    { 
     public static bool SchemaEquals(this DataTable dt, DataTable value) 
     { 
      if (dt.Columns.Count != value.Columns.Count) 
       return false; 

      var dtColumns = dt.Columns.Cast<DataColumn>(); 
      var valueColumns = value.Columns.Cast<DataColumn>(); 


      var exceptCount = dtColumns.Except(valueColumns, DataColumnEqualityComparer.Instance).Count() ; 
      return (exceptCount == 0); 


     } 
    } 

的IEqualityComparer實施

class DataColumnEqualityComparer : IEqualityComparer<DataColumn> 
    { 
     #region IEqualityComparer Members 

     private DataColumnEqualityComparer() { } 
     public static DataColumnEqualityComparer Instance = new DataColumnEqualityComparer(); 


     public bool Equals(DataColumn x, DataColumn y) 
     { 
      if (x.ColumnName != y.ColumnName) 
       return false; 
      if (x.DataType != y.DataType) 
       return false; 

      return true; 
     } 

     public int GetHashCode(DataColumn obj) 
     { 
      int hash = 17; 
      hash = 31 * hash + obj.ColumnName.GetHashCode(); 
      hash = 31 * hash + obj.DataType.GetHashCode(); 

      return hash; 
     } 

     #endregion 
    } 

輸出

dt1.SchemaEquals(dt1) | True 
dt1.SchemaEquals(dt2) | False 
dt1.SchemaEquals(dt3) | False 
dt1.SchemaEquals(dt4) | True 
dt1.SchemaEquals(dt5) | True 
Press any key to continue . . . 
+0

對不起..我現在澄清我的問題 – shergill

0

從康拉德答案肯定是有幫助的。但我用下面的方式來比較數據表結構。

Private Function CompareStruture(ByVal dt1 As DataTable, ByVal dt2 As DataTable) As Boolean 
     If (dt1.Columns.Count = dt2.Columns.Count) Then 
      Dim c1() = (From c As DataColumn In dt1.Columns Select c.ColumnName).ToArray() 
      Dim c2() = (From c As DataColumn In dt2.Columns Select c.ColumnName).ToArray() 
      If (c1.Intersect(c2).Count() <> c1.Length) Then      
       Return False 
      End If 
      Return True 
     Else     
      Return False 
     End If 
    End Function 
0

這是我爲我的項目所用​​的方法。我只測試了我關心的屬性的平等性。如果您關心的不僅僅是這裏的內容,您可以添加其餘的屬性。請注意,這裏沒有其他答案驗證主鍵匹配,而我的。

public static bool SchemaMatches(this DataTable table, DataTable referenceTable) 
{ 
    if(table.Columns.Count != referenceTable.Columns.Count || table.PrimaryKey.Count() != referenceTable.PrimaryKey.Count()) 
     return false; 
    foreach(DataColumn referenceColumn in referenceTable.Columns) 
    { 
     try { 
      DataColumn column = table.Columns[referenceColumn.ColumnName]; 
      if(column == null || !referenceColumn.AllowDBNull.Equals(column.AllowDBNull) || !referenceColumn.ColumnName.Equals(column.ColumnName) 
       || !referenceColumn.DataType.Equals(column.DataType) || !referenceColumn.Expression.Equals(column.Expression) || !referenceColumn.ReadOnly.Equals(column.ReadOnly)) 
      { 
       return false; 
      } 
     } catch { 
      return false; 
     } 
    } 
    foreach(DataColumn referenceKey in referenceTable.PrimaryKey) 
    { 
     try { 
      DataColumn key = table.PrimaryKey.Single(x=>x.ColumnName == referenceKey.ColumnName); 
      if(key == null) 
       return false; 
     } catch { 
      return false; 
     } 
    } 
    return true; 
} 
相關問題