C# 我可以使用LINQ来比较两个集合之间缺少、添加或更新的内容吗

C# 我可以使用LINQ来比较两个集合之间缺少、添加或更新的内容吗,c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,我有以下课程。为了便于比较,我添加了一个Equals方法: public ObjectiveDetail() public int ObjectiveDetailId { get; set; } public int Number { get; set; } public string Text { get; set; } public override bool Equals(object obj) { return this.Equa

我有以下课程。为了便于比较,我添加了一个Equals方法:

 public ObjectiveDetail()
    public int ObjectiveDetailId { get; set; }
    public int Number { get; set; }
    public string Text { get; set; }
    public override bool Equals(object obj)
    {
        return this.Equals(obj as ObjectiveDetail);
    }
    public bool Equals(ObjectiveDetail other)
    {
        if (other == null)
            return false;

        return this.Number.Equals(other.Number) &&
            (
                this.Text == other.Text ||
                this.Text != null &&
                this.Text.Equals(other.Text)
            );
    }
 }
我有两个ICollection集合:

ICollection<ObjectiveDetail> _obj1; // Reference
ICollection<ObjectiveDetail> _obj2; // May have more, less or different objectDetails from the reference.
ICollection\u obj1;//参考文献
i收集_obj2;//可能有更多、更少或与引用不同的objectDetails。
集合的公共tfield是ObjectiveDetailId。有没有一种方法可以使用三个LINQ表达式来创建:

  • _obj2和非_obj1中的行集合
  • _obj1和非_obj2中的行集合
  • 不同于_obj1和_obj2的行的集合

请注意,这与我之前问的另一个问题类似,但我认为现在我添加了Equals方法,这就简单了一点。uld可以这样做吗?

您应该始终覆盖
等于
获取hashcode

  • _obj2和非_obj1中的行集合

    var inObj2NotInObj1 = _obj2.Except(_obj1).ToList();
    
  • _obj1和非_obj2中的行集合

    var inObj1NotInObj2 = _obj1.Except(_obj2).ToList();
    
  • 不同于_obj1和_obj2的行的集合


如果您的意思不是
Equals
,请指定不同的值,这就是您上面的值。

您应该始终覆盖
Equals
GetHashCode

  • _obj2和非_obj1中的行集合

    var inObj2NotInObj1 = _obj2.Except(_obj1).ToList();
    
  • _obj1和非_obj2中的行集合

    var inObj1NotInObj2 = _obj1.Except(_obj2).ToList();
    
  • 不同于_obj1和_obj2的行的集合

如果您的意思是“不
等于”
,请指定不同的值,这就是您上面的值。

您可以使用它来减去集合:

var in2butNot1 = _obj2.Except(_obj1);
var in1butNot2 = _obj1.Except(_obj2);
但是,这可能不是您希望得到的结果,因为已“更改”的对象将被视为彼此“不相等”

您的对象似乎有一个
ID
字段。您可以对该
ID
上的对象进行排序,然后像生成合并一样遍历这两个集合。这将允许您通过一个简单的
if
s链来检测插入、更新和删除

您还可以使用ID来决定哪些是常见的,哪些是更改的:

var ids1 = new HashSet<int>(_obj1.Select(o => o.ObjectiveDetailId));
var ids2 = new HashSet<int>(_obj2.Select(o => o.ObjectiveDetailId));
var in2butNot1 = _obj2.Where(o => !ids1.Contains(o.ObjectiveDetailId));
var in1butNot2 = _obj1.Where(o => !ids2.Contains(o.ObjectiveDetailId));
var ids1=newhashset(_obj1.Select(o=>o.ObjectiveDetailId));
var ids2=newhashset(_obj2.Select(o=>o.ObjectiveDetailId));
变量in2butNot1=_obj2.Where(o=>!ids1.Contains(o.ObjectiveDetailId));
变量in1butNot2=_obj1.Where(o=>!ids2.Contains(o.ObjectiveDetailId));
您可以使用来减去集合:

var in2butNot1 = _obj2.Except(_obj1);
var in1butNot2 = _obj1.Except(_obj2);
但是,这可能不是您希望得到的结果,因为已“更改”的对象将被视为彼此“不相等”

您的对象似乎有一个
ID
字段。您可以对该
ID
上的对象进行排序,然后像生成合并一样遍历这两个集合。这将允许您通过一个简单的
if
s链来检测插入、更新和删除

您还可以使用ID来决定哪些是常见的,哪些是更改的:

var ids1 = new HashSet<int>(_obj1.Select(o => o.ObjectiveDetailId));
var ids2 = new HashSet<int>(_obj2.Select(o => o.ObjectiveDetailId));
var in2butNot1 = _obj2.Where(o => !ids1.Contains(o.ObjectiveDetailId));
var in1butNot2 = _obj1.Where(o => !ids2.Contains(o.ObjectiveDetailId));
var ids1=newhashset(_obj1.Select(o=>o.ObjectiveDetailId));
var ids2=newhashset(_obj2.Select(o=>o.ObjectiveDetailId));
变量in2butNot1=_obj2.Where(o=>!ids1.Contains(o.ObjectiveDetailId));
变量in1butNot2=_obj1.Where(o=>!ids2.Contains(o.ObjectiveDetailId));
“不等于”的意思是当对象具有相同的 ObjectiveDetailId,但不同的“数字”或“文本”字段值

如果创建一个将ID映射到原始(_obj1)对象的字典,则可以使用每个新(_obj2)对象的匹配ID查找原始对象,并比较:

var oldDictionary = _obj1.ToDictionary(old => old.ObjectiveDetailId);
var updated = _obj2.Where(current => {
    ObjectiveDetail old = null;
    var isExisting = oldDictionary.TryGetValue(current.ObjectiveDetailId, out old);
    return isExisting && !old.Equals(current);
});
“不等于”的意思是当对象具有相同的 ObjectiveDetailId,但不同的“数字”或“文本”字段值

如果创建一个将ID映射到原始(_obj1)对象的字典,则可以使用每个新(_obj2)对象的匹配ID查找原始对象,并比较:

var oldDictionary = _obj1.ToDictionary(old => old.ObjectiveDetailId);
var updated = _obj2.Where(current => {
    ObjectiveDetail old = null;
    var isExisting = oldDictionary.TryGetValue(current.ObjectiveDetailId, out old);
    return isExisting && !old.Equals(current);
});

非常感谢。我理解Except,但是你能给我一个例子,说明我如何创建一个存在于两个组中但不相等的对象列表吗?我正在考虑使用For循环。但是你使用Except的方法看起来容易多了。使用你的方式不是更好吗?@Alan不,因为
Except
不区分“更改”和“插入”。如果两个对象不相等,
Except
将它们视为“插入”,即使它们的
objectiveDetail
s可能相同。我将使用稍加修改的方法编辑更多内容。我将行存储在关系表中,我想我需要做的是使用对象作为参数生成添加、更新和删除。我不确定这对你的建议是否有影响。但我想我需要一个删除、更新和插入的列表。我认为你关于遍历集合的建议可能是最好的。我将把这个问题标记为已回答,并重新措辞。非常感谢。我理解Except,但是你能给我一个例子,说明我如何创建一个存在于两个组中但不相等的对象列表吗?我正在考虑使用For循环。但是你使用Except的方法看起来容易多了。使用你的方式不是更好吗?@Alan不,因为
Except
不区分“更改”和“插入”。如果两个对象不相等,
Except
将它们视为“插入”,即使它们的
objectiveDetail
s可能相同。我将使用稍加修改的方法编辑更多内容。我将行存储在关系表中,我想我需要做的是使用对象作为参数生成添加、更新和删除。我不确定这对你的建议是否有影响。但我想我需要一个删除、更新和插入的列表。我认为你关于遍历集合的建议可能是最好的。我将此标记为已回答,并重新表述问题。您所说的“行”是否意味着列表元素的索引很重要?例