DataRowComparer除了长行比较失败

时间:2012-08-06 13:17:22

标签: c# linq datatable comparison

晚上好,

我正在构建一种比较两个数据表(最后一个读取和我需要写入的数据)并仅检索已修改行的缓存。 我使用DataRowComparer.Default作为Equality Comparer,但它的目标是将行与多个字段进行比较。

它与具有短文本值的3列表完美配合,但是比较长文本描述即使我更改了单个字符,也无法返回整个表。

代码非常简单:

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

想法? 谢谢!

更新 手动调试我能够比较ds.Tables [0] .AsEnumerable()行与cachedtable.AsEnumerable()行:绝对等于但不同于DataRowComparer除外。我删除了任何DateTime列,试图避免格式差异而没有成功。 交叉点也不起作用。

更新2: 除了不适用于空/空字段。它们似乎与IEqualityComparer不同。

1 个答案:

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

正如您所看到的,null值和DBNull被不同地考虑,并且null == DBNull始终为false。显然,空字符串看起来像空字段,但它不是DBNull。 因此,由于这个空值,两个显然相似的表是不同的。 我的解决方案解析ds.Tables [0],同时从xml源构建(这是一个空字符串和空值)并使用System.Convert.DBNull进行替换

现在比较完美。

P.S。如果从sql查询或xml源构建数据表,\ n和\ r \ n也不同。容易解决假设上面的null / DBNull解决方案。