2011-09-05 82 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; 
} 
相关问题