2009-04-08 8 views
1

抽象基本クラスでEqualsとGetHashCodeをオーバーライドして、オブジェクトのキープロパティに基づいて値の等価性を実装しました。私の主な目的は、コレクションにContainsメソッドを使用して、FindまたはFirstOrDefaultの代わりにインスタンスがコレクションに既に追加されているかどうかを確認できるようにすることです。新しいオブジェクトの値の等値比較

public abstract class Entity 
{ 
    public abstract Guid Id { get; } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
     { 
      return false; 
     } 

     if (obj.GetType() != GetType()) 
     { 
      return false; 
     } 

     var entity = (Entity)obj; 
     return (entity.Id == Id); 
    } 

    public override int GetHashCode() 
    { 
     return Id.GetHashCode(); 
    } 

} 

このアプローチの問題は、永続化され、Id(NHibernateによって生成された)を取得する前にすべてのオブジェクトが等しいことです。私はそれを間違っているのですか?私はコンストラクタでIdを生成することができましたが、int iidを使用する他のプロジェクトでも同じパターンを実装したいので、明らかに動作しません。

オブジェクトがインスタンス化された直後に、等しいオブジェクトをオーバーライドするオブジェクトは、同じオブジェクトの他のインスタンスと等しくなります。

は編集を追加する: をここで私に関するシナリオです:私のコレクションのAddメソッドでは、私はコレクションはすでに追加されるオブジェクトが含まれていないことを確認するためにチェックしています。 new'ed upオブジェクトがすべて等しい場合、コレクションに2つの新しいオブジェクトを追加することはできません。

答えて

2

同じコンテキストでアソシエートされたエンティティの参照IDをオブジェクトにするNHibernateガランスは、データベースIDと同じです。したがって、Equals()とGetHashCode()をオーバーライドする必要はありません。これは、実装するIDと同一のIDなのでです。

NHibernate Reference Documentation10.3. Considering object identityを参照してください。

また、コンテキストでデータベース生成キーを使用して新しいエンティティを割り当てることは、エンティティをデータベースに永続的に保持し、エンティティのキ​​ーを生成されたキーに設定する必要があります。

+0

良い点...私はISession間でコレクションの参照を保持しているとは思いません。 –

1

コンストラクタでIDまたは少なくとも何らかの識別子を取得する必要があります。

IDが設定されていない(またはデフォルト値です)場合。明らかにEqualsメソッドは同じタイプのオブジェクト(IDも設定していないオブジェクト)に対してtrueを返します。

+0

私はそれを試してみるまで、私には分かりませんでした、ありがとう。 –

0

IDが初期化されていない場合に "等しくない"を返すと役立ちますか?

public override bool Equals(object obj) 
{ 
    if (obj == null) 
    { 
     return false; 
    } 

    if (obj.GetType() != GetType()) 
    { 
     return false; 
    } 

    var entity = (Entity)obj; 
    if ((Id == Guid.Empty) || (entity.Id == Guid.Empty)) 
    { 
     return false; 
    } 
    return (entity.Id == Id); 
} 
0

あなたの決定に影響を与える一つの大きな詳細があります:

...私は int型のIDを使用する他のプロジェクトのために同じ パターンを実装したいと思います...

通常、データベース内でIDが生成され、の一意性がに適用されます。 GUIDがあるので、値を生成するためにデータベースに頼る必要はありません - GUIDは一意であることが保証されています。間違った理由でパターンを守らないでください:)

したがって、コンストラクタでGUID値を作成してください。ちょうど、Hibernateがデータベースからエンティティをフェッチするときに値を上書きできるように設定してください。

DBAがGUIDおよびデータベースの断片化に関係する場合は、COMB GUIDsを使用することを検討することもできます。

関連する問題