晚上好,
我正在构建一种比较两个数据表(最后一个读取和我需要写入的数据)并仅检索已修改行的缓存。 我使用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不同。
答案 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解决方案。