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 の日付があります。1つを削除してから を呼び出しLazySave、10個のアイテムを渡しますが、結果TListは返されず、 orIntersectにもヒットしません。任意のアイデア> 私はそれが私の比較者に関係していると思います...EqualsGetHashCode

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

を使用しているときにカスタムEqualsGetHashCodeメソッドが呼び出されていない場合は、 or(ちなみに奇妙なパラメーター名)のいずれIntersectかが空であることを示しています。 allItems TList

于 2013-01-28T16:19:34.213 に答える
0

IEqualityComparer は、オブジェクトのインスタンスを比較するために使用される外部クラスを対象としていると思いますか?

BankHoliday クラスで、オーバーライドを使用して IEquatable を実装してみてください。

public override bool Equals(object obj)

public override int GetHashCode()

EDIT : @Jon の Except コード例を使用します。

于 2013-01-28T16:27:06.887 に答える