IEnumerable 在泛型方法中与比较器相交
本文关键字:比较器 泛型方法 IEnumerable | 更新日期: 2023-09-27 17:56:33
我正在我的基本数据访问层(BaseDAL
)中为对象数据库创建一个LazySave<T>
。
public void LazySave<T>(IEnumerable<T> TList, Func<T, T, bool> condition, IEqualityComparer<T> comparer) where T : class
{
//Select where GetOne<T> returns null, meaning this item doesn't exist
var itemsToStore = TList.Where(TItem => GetOne<T>(e => condition(TItem, e)) == null);
//Select where GetOne<T> returns not null, meaning this item exists
var itemsToUpdate = TList.Where(TItem => GetOne<T>(e => condition(TItem, e)) != null);
//Get all of the items
var allItems = GetMany<T>();
//Any items which aren't in TList but are in the original list need to be deleted
var itemsToDelete = TList.Intersect(allItems, comparer);
itemsToStore.ToList().ForEach(i => Store<T>(i));
itemsToUpdate.ToList().ForEach(i => Update<T>(i, condition));
itemsToDelete.ToList().ForEach(i => Delete<T>(i, condition));
}
我传递以下对象并与该方法进行比较。
public class BankHoliday : IBankHoliday, IEquatable<BankHoliday>
{
public DateTime Date { get; set; }
public bool Equals(BankHoliday other)
{
return other.Date == Date;
}
}
public class BankHolidayComparer : IEqualityComparer<BankHoliday>
{
public bool Equals(BankHoliday x, BankHoliday y)
{
return x.Date == y.Date;
}
public int GetHashCode(BankHoliday obj)
{
if (object.ReferenceEquals(obj, null)) return 0;
return obj.Date.GetHashCode();
}
}
称为:
var comparer = (IEqualityComparer<BankHoliday>)new BankHolidayComparer();
bhDAL.LazySave<BankHoliday>(holidays, ((T, T2) => T.Date == T2.Date), comparer);
数据库中的列表有 11 个日期。我删除了一个,然后调用LazySave
,将 10 个项目传递到TList
中,但是Intersect
没有返回任何结果,甚至没有命中Equals
或GetHashCode
。任何想法>我认为这与我的比较器有关......
根据你的评论,你误解了Intersect
的目的:
//Any items which aren't in TList but are in the original list need to be deleted
var itemsToDelete = TList.Intersect(allItems, comparer);
Intersect
查找两个序列中的项目。根据您的评论,我怀疑您想要Except
:
var itemsToDelete = allItems.Except(TList, comparer);
如果在使用 Intersect
时未调用自定义Equals
和GetHashCode
方法,则表明allItems
或TList
(顺便说一下,这是一个奇怪的参数名称)为空。
我相信
IEqualityComparer是为用于比较对象实例的外部类而设计的?
在 BankHoliday 类中,尝试使用覆盖实现 IEquatable:
public override bool Equals(object obj)
和
public override int GetHashCode()
编辑:并使用@Jon的除外代码示例。
这可能是一个愚蠢的问题,但只是为了确认 - 你把你的断点放在比较器的 Equals 和 GetHashCode 上?(不是银行假日的方法)
此外,由于对相交的惰性计算,在命中断点之前必须调用下面的行。
itemsToDelete.ToList().ForEach(i => Delete<T>(i, condition));