【问题标题】:Compare Two Datasets - Find Changes - LINQ比较两个数据集 - 查找更改 - LINQ
【发布时间】:2013-08-29 18:45:28
【问题描述】:

我已经在互联网上搜索并尝试找到解决方案,但也许我没有以正确的方式解决这个问题。

我需要比较两个结构相同的数据集,并希望找到新的和更改的对象(使用 LINQ)。

使用我在CodeProject 找到的内容,我能够汇总已更改的项目列表,但这是通过对每一列(并且会有很多列)进行硬编码并检查相同的值来完成的:

var updRec = from u in updated
             join o in orig
                on u.KeyValue equals o.KeyValue
             where
                (o.Propery1 != u.Propery1) ||
                (o.Propery2 != u.Propery2)
             select new record
             {
                 KeyValue = u.KeyValue,
                 Propery1 = u.Propery1,
                 Propery2 = u.Propery2 ,
                 RecordType = "mod" // Modified
             };

我可以在两件事上使用帮助:

  1. 是否有更有效的方法来遍历每一列,因为我计划添加更多需要比较的属性?必须有更好的方法来动态检查 2 个相同数据集的变化。
  2. 我如何查看哪些属性发生了变化?例如,为所有不相同的项目创建一个“Property、OriginalValue、UpdatedValue”列表?

希望这能很好地解释它。如果我没有正确看待它,请随时向我指出处理这种情况的其他方法。

【问题讨论】:

  • 您可以在 record 对象中覆盖 Equals() 并在那里进行比较。然后您可以将您的where 子句更改为where o.Equals(u)。但这只是将比较转移到一个更封闭的地方。如果你想要更多的自动化,你可能需要使用反射。
  • 您可能必须列出所有列,也许我只是不知道更好的方法,但我知道在 TSQL 中您必须列出所有列以比较增量,尽管有一些 groupby 技巧可以更快地进行比较.
  • 你如何定义改变?我最近偶然发现了类似的问题,我创建了一个方法,它结合了 2 个相同类型的对象,从属性不是 null 或默认值的对象中获取值,它还提供了一个选择优先对象的选项,以防万一这两个属性都有一个值。如果这是您可能想要的东西,请告诉我,我将发布带有代码和更好解释的答案。

标签: c# linq


【解决方案1】:

您可以使用 LINQ except() 扩展方法。这将返回列表中的所有内容,但第二个列表中的内容除外。

var orignalContacts = GetOrignal();
var updatedContacts = GetUpdated();

var changedAndNew = updatedContacts.Except(orignalContacts);
var unchanged     = orignalContacts.Except(updatedContacts);

根据您的数据提供者,您可能需要覆盖对象上的 Equals() 和 GetHashCode()。

【讨论】:

    【解决方案2】:
    1. 速度更快,但如果添加新属性,则需要维护代码是编写自定义比较器并使用您的方法。
    2. 较慢的使用反射遍历所有属性并动态比较它们

      IDictionary<string, Tuple<object, object>> GetDifferentProperties<T>(T keyValue1, T keyValue2)
      {
         var diff = new Dictionary<string, object>();
         foreach (var prop in typeof(T).GetProperties(BindingFlags.Public))
         {
            var prop1Value = prop.GetValue(keyvalue1);
            var prop2Value = prop.GetValue(keyValue2);
            if (prop1Value != prop2Value)
              diff.Add(prop.Name, Tuple.Create(prop1Value, prop2Value));
         }
         return diff;
      }
      

    然后在你的代码中

        var = results = (from u in updated
                        join o in orig
                        select new
                        {
                           Value1 = o.KeyValue,
                           Value2 = u.KeyValue
                        }).ToArray()
                        .Select(x => GetDifferentProperties(x.Value1, x.Value2))
                        .Select(DoSomestufWithDifference);
    

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 2011-07-30
      • 2014-12-10
      • 1970-01-01
      • 2015-07-10
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多