web-dev-qa-db-ja.com

NHibernateのリストvsセットvsバッグ

NHibernateマッピングファイルのリスト、セット、バッグの違いは何ですか?それぞれが.NETコレクションにどのように関連していますか?

102
mrblah

NHibernateセマンティクス:

  1. リスト:順序付けられたエンティティのコレクション、複製が許可されます。コードで.NET IListを使用します。 NHibernateでインデックス列をマップする必要があります。

  2. セット:一意のエンティティの順序なしコレクション、重複は許可されません。コードでIesi.Collection.ISet(v4より前のNH)またはSystem.Collections.Generic.ISet(NH v4 +)を使用します。 GetHashCodeEqualsをオーバーライドして、重複のビジネス定義を示すことが重要です。 orderbyを定義するか、比較結果を定義してSortedSet結果を生成することにより、ソートできます。

  3. バッグ:エンティティの順序なしリスト、重複は許可されています。コードで.NET ICollection<T>を使用します。リストのインデックス列は、NHibernateによってマップされず、尊重されません。

221
Michael Gattuso

NHibernateのこれらのオブジェクトはすべて、これらの抽象データ型(ADT)の他の実装とまったく同じです。セットやバッグをオンラインで見つけるのがどれほど難しいか、他の名前の名前がどれほど一般的であるかに驚いたので、ここにいくつかのリンクと説明をリストしました。

詳細については、以下を参照してください。 リストセット 、および バッグ

一般的な規則は次のとおりです。

Listsはデフォルトで順序付けられています。インデックスでオブジェクトを引き出したい場合、またはforに対するforeachループの奇妙な好みがある場合、これらを使用しますループ。 Linked List で必要になるような順序でアクセスする必要はありません。このADTは複製を許可します。

注意してください!リストは、BryanDが彼の答えで述べたように順序付けられていますが、あなたがデータベースに期待する順序にならなければならないということはまったくありませんコマンドによる順序を指定しない限り、HQLクエリを実行します。これは、一部の人々が代わりにSetまたはBagsを使用することを好むためです。私はこれを言いますが、ほとんどの場合、NHibernateが実行するクエリで見つかった順序でリストに追加されるため、目に見える順序で表示されます。

Setsnotです。デフォルトでは順序付けされており、インデックスを介して変数に直接アクセスすることはできません。デフォルトでは、セットはオブジェクトの一意性を維持する上記3つのうちADTのみです。重複を含まないようにする必要がある場合にコレクションがある場合、これらは素晴らしいです。

Bags(またはMultisets)は、上記のリンクからわかるように、その中のオブジェクトを他のオブジェクトの複製にすることができるSetのタイプです。リストの順序は無視でき、したがってバッグとして扱われるため、これらは通常使用されません。

これらがNHibernateでどのように使用されるかに関連して、ここで選択するADTに応じてデータベースから何もプルされません。異なるADTを選択するために使用するものです。

個人的には、通常は子オブジェクトを一意にする必要があるため、ほとんどのものにセットを使用します。順序は問題ではありません。この順序を実現するために、たとえば時間などで順序付けするオブジェクトのグループがあるリストを使用しますが、HQLクエリで「順序」を手動で設定する必要があります。

21
Jay

主な違いは、リストには要素の暗黙的な順序があり、リスト内の位置によってインデックスが付けられることです。セットとバッグは、通常、Comparatorによって、またはそれらのアイテムがDBから出てくるときに適用されるorder by句によって「注文」される場合もあります。個人的には、Bagsを使用したことはありません...必要なデータが順番に並んでいることがわかっている場合はListを使用し、そうでない場合はSetを使用します。

1
BryanD

Setでは、要素を繰り返し使用できません。新しい要素を追加しようとすると、既にコレクションにある各要素と追加する要素が比較されます(等しいメソッドが使用されます)。

0
Sly