c# - 使用 LINQ。有两个不同的列表。如何识别不匹配的对象

标签 c# linq

我有三个类(class):

public partial class Objective{
    public Objective() {
        this.ObjectiveDetails = new List<ObjectiveDetail>();
    }
    public int ObjectiveId { get; set; }
    public int Number { get; set; }
    public virtual ICollection<ObjectiveDetail> ObjectiveDetails { get; set; }
}
public partial class ObjectiveDetail {
    public ObjectiveDetail() {
        this.SubTopics = new List<SubTopic>();
    }
    public int ObjectiveDetailId { get; set; }
    public int Number { get; set; }
    public string Text { get; set; }
    public virtual ICollection<SubTopic> SubTopics { get; set; }
}
public partial class SubTopic {
    public int SubTopicId { get; set; }
    public string Name { get; set; }
}

我有两个列表:

IList<ObjectiveDetail> oldObj;
IList<ObjectiveDetail> newObj;

以下 LINQ 为我提供了一个新的 ObjectiveDetail 对象列表,其中:列表中任何 ObjectiveDetail 对象的 Number 或 Text 字段在 oldObjnewObj

IList<ObjectiveDetail> upd = newObj
    .Where(wb => oldObj
        .Any(db => (db.ObjectiveDetailId == wb.ObjectiveDetailId) && 
                   (db.Number != wb.Number || !db.Text.Equals(wb.Text))))
     .ToList();

我如何修改它以便 LINQ 给我一个新的 ObjectiveDetail 对象列表,其中:任何 的数字或文本字段或子主题集合列表中的 ObjectiveDetail 对象在 oldObjnewObj 之间有所不同。

换句话说,如果满足以下条件,我希望将 ObjectiveDetail 添加到 upd 列表中:

  • oldObj 中的文本与 newObj 中的文本不同
  • oldObj 中的 Number 与 newObj 中的 Number 不同
  • 它有一个 SubTopics 集合,其中包含 oldObj 中的三个元素和 newObj 中的 4 个元素
  • 它有一个 SubTopics 集合,在 oldObj 中没有元素,在 newObj 中有 2 个元素
  • 它有一个 SubTopics 集合,在 oldObj 中有 2 个元素,在 newObj 中没有元素
  • 它有一个 SubTopics 集合,其元素的 SubTopicId 在 oldObj 中为 1 和 2,在 newObj 中为 1 和 3

我希望有人可以在我已有的 LINQ 语句中想出一些额外的行。

最佳答案

我不会创建一个庞大且难以维护的 LINQ 查询来尝试查找差异,而是在两个列表(交集)中创建一个相同对象的列表,结果是,对除此交集之外的两个集合求和。要比较对象,您可以使用 IEqualityComparer<>执行。这是草稿:

public class ObjectiveDetailEqualityComparer : IEqualityComparer<ObjectiveDetail>
{
    public bool Equals(ObjectiveDetail x, ObjectiveDetail y)
    {
        // implemenation                          
    }

    public int GetHashCode(ObjectiveDetail obj)
    {
        // implementation
    }
}

然后简单地:

var comparer = new ObjectiveDetailEqualityComparer();
var common = oldObj.Intersect(newObj, comparer);
var differs = oldObj.Concat(newObj).Except(common, comparer);

当类更改(新属性等)时,这将更容易维护。

关于c# - 使用 LINQ。有两个不同的列表。如何识别不匹配的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21274521/

相关文章:

c# - LINQ to SQL 在更新后返回旧数据

sql - 编写 SQL 查询的方式会影响性能吗?

c# - 翻转/滑动效果与 Winforms

c# - Unity - 未检测到命名空间

c# - 是否可以将小型查询合并为单个查询?

c# - CSVHelper 版本 2,.QuoteAllFields 属性消失了,用什么来代替它?

LINQ 运算符 '==' 不能应用于 'method group' 和 'int' 类型的操作数

c# - 使用 Linq,如何按名称将列表分隔为分组对象?

c# - LINQ优化的问题

c# - Linq-To-SQL 中的 Hacker News 风格排序算法