检查2数据表是否具有相同的模式

时间:2011-09-05 22:34:36

标签: ado.net datatable

我想确保2个Ado.net数据表具有相同的模式:列数+列类型等。如何做到这一点?


假设我有变量:Datatable A和Datatable B.我如何比较以查看A的架构是否与B的架构相同

3 个答案:

答案 0 :(得分:8)

我不知道有任何内置的比较DataTables的方法,也没有定义完整的规范(and you always should),我可能会错过一些你关心的案例。

那说以下确实设法比较两个DataTable并确定以下是否为真

  • 两个DataTables中的数据列数是否相同
  • 对于第一个dataTable中的每个数据列,一个列存在于另一个表中,该列具有相同的类型,无论顺序如何

它正在使用扩展方法并实现IEqualityComparer来进行比较。

测试用例

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 . . .

答案 1 :(得分: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

答案 2 :(得分: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;
}