我想确保2个Ado.net数据表具有相同的模式:列数+列类型等。如何做到这一点?检查2个数据表是否具有相同的模式
可以说我有变量:DataTable中的一个和DataTable B.我如何比较,看看A的模式是相同的为B
我想确保2个Ado.net数据表具有相同的模式:列数+列类型等。如何做到这一点?检查2个数据表是否具有相同的模式
可以说我有变量:DataTable中的一个和DataTable B.我如何比较,看看A的模式是相同的为B
我不知道任何内置的架构在比较DataTables的方式中,并且没有定义完整的规范(and you always should),可能我会错过某些您关心的案例。
认为下列情况管理比较两个数据表,并确定以下各项为真
它使用扩展方法和实现的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 . . .
从康拉德答案肯定是有帮助的。但我用下面的方式来比较数据表结构。
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
这是我为我的项目所用的方法。我只测试了我关心的属性的平等性。如果您关心的不仅仅是这里的内容,您可以添加其余的属性。请注意,这里没有其他答案验证主键匹配,而我的。
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;
}
对不起..我现在澄清我的问题 – shergill