我想確保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