2012-08-06 78 views
3

晚上好,DataRowComparer除了上排着長長比較

我建立了一種高速緩存比較兩個數據表(最後一次讀取和一個我需要寫)和僅檢索修改的行失敗。 我使用DataRowComparer.Default作爲Equality Comparer,但它有錯誤的目標比較行與許多領域。

它可以很好地處理帶有短文本值的3列表格,但是比較長文本描述時,即使我更改了單個字符,也無法返回整個表格。

的代碼非常簡單:

var diffDs = ds.Tables[0].AsEnumerable().Except(cachedTable.AsEnumerable(), DataRowComparer.Default); 

想法? 謝謝!

更新: 手動調試,我能夠比較ds.Tables [0] .AsEnumerable()行VS cachedtable.AsEnumerable()行:絕對等於爲DataRowComparer除,但不同的。我已經刪除了任何試圖避免格式差異而沒有成功的日期時間列。 相交不起作用。

更新2: 除空/空字段不起作用。它們對於IEqualityComparer似乎不同。

+0

您能否將您的解決方案轉換爲答案並將其標記爲已接受(可能在兩天後)? – 2012-08-08 23:06:47

+1

將我的解決方案轉換爲答案並標記! – 2012-08-09 08:05:16

回答

0

我找到了一個解決方案:

DataRowComparer代碼是這樣的:

internal static bool AreEqual(object a, object b) 
    { 
     if (Object.ReferenceEquals(a, b)) 
     { // same reference or (null, null) or (DBNull.Value, DBNull.Value) 
      return true; 
     } 
     if (Object.ReferenceEquals(a, null) || Object.ReferenceEquals(a, DBNull.Value) || 
      Object.ReferenceEquals(b, null) || Object.ReferenceEquals(b, DBNull.Value)) 
     { // (null, non-null) or (null, DBNull.Value) or vice versa 
      return false; 
     } 
     return (a.Equals(b) || (a.GetType().IsArray && CompareArray((Array)a, b as Array))); 
    } 

正如你可以看到空值和DBNull的是不同的考慮和空== DBNull的永遠是假的。顯然,一個空字符串看起來像空字段,但它不是DBNull。 因此,由於這個空值,兩個表格明顯相似。 我的解決方案解析ds.Tables [0],同時從xml源(這是一個空字符串和空值)構造,並操作替換與System.Convert.DBNull

現在,比較完美。

P.S. \ n和\ r \ n也不同,如果您從sql查詢或從xml源生成數據表。易於解決假定上面的null/DBNull解決方案。