C# 我可以使用LINQ来比较两个集合之间缺少、添加或更新的内容吗
我有以下课程。为了便于比较,我添加了一个Equals方法: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
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可能相同。我将使用稍加修改的方法编辑更多内容。我将行存储在关系表中,我想我需要做的是使用对象作为参数生成添加、更新和删除。我不确定这对你的建议是否有影响。但我想我需要一个删除、更新和插入的列表。我认为你关于遍历集合的建议可能是最好的。我将此标记为已回答,并重新表述问题。您所说的“行”是否意味着列表元素的索引很重要?例