0

我正在LazySave<T>我的基础数据访问层 ( BaseDAL) 中为对象数据库创建一个。

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没有返回结果,甚至没有命中Equalsor GetHashCode。任何想法>我认为这与我的比较器有关...

4

3 回答 3

0

这可能是一个愚蠢的问题,但只是为了确认 - 您将断点放在比较器的 Equals 和 GetHashCode 上?(不是 BankHoliday 的方法)

此外,由于对相交的延迟评估,必须在击中断点之前调用下面的行。

itemsToDelete.ToList().ForEach(i => Delete<T>(i, condition));
于 2013-01-29T10:12:07.803 回答
0

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);

如果您的 customEqualsGetHashCode方法在 using 时没有被调用Intersect,则表明or (顺便说一句, 是一个奇怪的参数名称)为空。allItems TList

于 2013-01-28T16:19:34.213 回答
0

我相信 IEqualityComparer 适用于用于比较对象实例的外部类?

在 BankHoliday 类上,尝试使用覆盖实现 IEquatable:

public override bool Equals(object obj)

public override int GetHashCode()

编辑:并使用@Jon 的例外代码示例。

于 2013-01-28T16:27:06.887 回答