c# - 使用 Linq 除了返回从列表中删除但具有相同 ID 的项目
问题描述
我有以下列表:
var previousRun = new List<Data>();
var currentRun = new List<Data>();
var item1= new Data() { Id = "1", Address = "Test Address", Name = "Test", PostCode = "ABC DEF" };
var item2 = new Data() { Id = "2", Address = "Test Address2", Name = "Test2", PostCode = "GHI JKL" };
var item1Updated = new Data() { Id = "1", Address = "UpdatedAddress", Name = "UpdatedTest", PostCode = "STU VWX" };
var item2Updated= new Data() { Id = "2", Address = "UpdatedAddress2", Name = "Test2", PostCode = "TES TIN" };
previousRun.Add(item1);
previousRun.Add(item2);
currentRun.Add(item1updated);
currentRun.Add(item2updated);
我正在尝试计算从当前列表中的上一个列表中删除的项目数:
public DataChange<Data>[] Compare(Data[] previous, Data[] current)
{
var deletedResults = previous
.Except(current)
.Select(DataChange<Data>.Deleted)
.ToList();
}
在这种情况下,我希望结果为 0,因为没有任何内容被删除,只有更新(我很欣赏可以说原件已被“删除”,但我也会有一个更新项目的列表,所以删除真的意味着ID 已被删除。
取而代之deletedResults
的是 2,因为它认为两个原始项目都已被删除。如果 Id 在上一个列表中但不在当前列表中,任何人都可以请帮助进行 Linq 查询,该查询只会将项目显示为“已删除”。
更新
我已经按照评论中的建议实施了 EqualityComparer:
public class DataEqualityComparer: IEqualityComparer<GpLookupData>
{
public bool Equals(Data previous, Data current)
{
var idComparer = string.Equals(previous.Id, current.Id, System.StringComparison.OrdinalIgnoreCase);
var nameComparer = string.Equals(previous.Name, current.Name, System.StringComparison.OrdinalIgnoreCase);
var addressComparer = string.Equals(previous.Address, current.Address, System.StringComparison.OrdinalIgnoreCase);
var postcodeComparer = string.Equals(previous.PostCode, current.PostCode, System.StringComparison.OrdinalIgnoreCase);
if (idComparer && nameComparer && addressComparer && postcodeComparer)
{
return true;
}
return false;
}
public int GetHashCode(Data obj)
{
return obj.Name.GetHashCode();
}
}
解决方案
.Except()
IEqualityComparer<T>
如果 a未指定,将使用默认的相等比较器。
默认相等比较器将使用以下逻辑:
- 如果类型实现
IEquatable<T>
,请使用bool Equals(T other)
方法 - 如果类型覆盖
bool Equals(object)
,请使用它。 - 如果类型是引用类型,请使用
ReferenceEquals(object, object)
. 如果类型是值类型,则将比较类型中的每个字段。
我的猜测是 Data-type 是一个引用类型,它不会覆盖任何 equals 方法,因此将使用引用相等。因此,您需要定义对象的比较方式。
如果您实现/覆盖任何 equals 方法,请记住也要覆盖该GetHashCode()
方法。