1

私はnhibernateを初めて使用します。これが私がやろうとしていることです。

人々のテーブルと彼らに割り当てられたスケジュールIDをデータベースから取得します。このテーブルのレコードは、personオブジェクトで表されます。人の集まりを人と呼びましょう。UIで、このコレクションに個人を追加したり、個人を削除したり、個人に関連付けられたスケジュールIDを変更したりできます。UIでこれらすべての変更を行い、peopleオブジェクト(personsのコレクション)をサービスレイヤーに送信します。

サービスレイヤー:

私がこれをするなら

people.ForEach(x => INHibernateLinqRepository<person>.Save(x));

ピープルコレクションの全員をテーブルに挿入します。そのIDがデータベースにすでに存在する場合、更新されるはずではありませんか?

これは私が試した別のことです。サービスがUIからユーザーを取得した後、データベースから別のコレクションにユーザーを取得します。次に、2つを比較して、どちらを更新し、どちらを保存するかを決定します。次に、新しいアイテムに対してのみ保存を呼び出します。しかし、それはエラーをスローします

a different object with the same identifier value was already associated with the session:

私はイライラしています。誰かが私を助けることができますか?

4

1 に答える 1

3

NHibernateは、セッション内のオブジェクトの独自のリストを維持します(「第1レベルのキャッシュ」と呼ばれることもあります)。データベースからオブジェクトをロードするたびに、NHibernateセッションはそれを内部ディクショナリに格納します。これはIDマップの実装です。

オブジェクトIDは辞書キーです。同じセッションを使用して同じエンティティを再度ロードしようとすると、NHibernateはデータベースに移動せず、セッションからオブジェクトを返します。

比較を行うためにデータベースからアイテムをロードすると、NHibernateはそれらをセッションに保存します。その後、サービスレイヤーに送信した同じオブジェクト(同じID)の別のインスタンスを保存しようとしています。NHibernate、つまり内部IDマップでは、同じIDのアイテムが既にキャッシュにあるため、これを行うことはできません。

データベースからアイテムをロードして手動で比較する必要はありません。NHibernateは、それ自体でこれを行うのに十分賢いです。を呼び出す必要がありますsession.SaveOrUpdate(object)。オブジェクトIDが割り当てられていない場合は、挿入を実行します。id値がある場合は、代わりに更新されます。

于 2012-08-27T12:34:37.207 に答える