2012-08-06 26 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解决方案。