Nhibernate-inverse-relationships
NHibernate-逆関係
この章では、逆関係というもう1つの機能について説明します。 これは、コレクションに逆にtrueと等しい面白いオプションであり、多くの開発者を混乱させます。 それでは、このオプションについて話しましょう。 これを理解するには、リレーショナルモデルについて考える必要があります。 単一の外部キーを使用する双方向の関連付けがあるとします。
リレーショナルの観点から、1つの外部キーを取得しました。これは、注文する顧客と注文する顧客の両方を表します。
OOモデルから、これらの参照を使用した単方向の関連付けがあります。
2つの単方向の関連付けがデータベース内の同じ双方向の関連付けを表しているという説明はありません。
ここでの問題は、NHibernateには customer.orders と order.customer がデータベース内の同じ関係を表すことを知るのに十分な情報がないことです。
ヒントとして inverse equals true を提供する必要があります。これは、単方向の関連付けが同じデータを使用しているためです。
2つの参照を持つこれらの関係を保存しようとすると、NHibernateはその参照を2回更新しようとします。
実際には、データベースへの余分なラウンドトリップを実行し、その外部キーに対して2つの更新も行います。
逆の値がtrueの場合、NHibernateは関係のどちらの側を無視するかを指示します。
これをコレクション側に適用すると、NHibernateは常に、子オブジェクト側から反対側から外部キーを更新します。
その後、その外部キーに対する更新は1つだけであり、そのデータに対する追加の更新はありません。
これにより、外部キーに対するこれらの重複した更新を防ぐことができ、外部キー違反の防止にも役立ちます。
これが Program.cs ファイルの実装です。
それをデータベースに保存してからリロードします。 それでは、アプリケーションを実行してNHibernate Profilerを開き、実際にどのように保存されたかを見てみましょう。
3つのグループのステートメントがあることに気付くでしょう。 最初の1つは顧客を挿入し、その顧客のIDはGuidであり、強調表示されています。 2番目のステートメントは、ordersテーブルへの挿入です。
同じCustomer Id Guidがそこに設定されていることに気付くので、その外部キーを設定します。 最後のステートメントは更新であり、外部キーを再度同じ顧客IDに更新します。
問題は、顧客に注文があり、注文に顧客がいるということです。NHibernateに実際には同じ関係であることを伝えなかったわけではありません。 これを行う方法は、逆がtrueの場合です。
次のコードに示すように、 customer.hbm.xml マッピングファイルに移動し、逆数をtrueに設定します。
注文を保存するとき、注文側からその外部キーを設定します。 次に、このアプリケーションを再度実行して、NHibernateプロファイラーを開きます。
それらがどのように挿入されるかを見ると、顧客への挿入とオーダーへの挿入を取得しますが、オーダーの保存時に更新されているため、外部キーの重複した更新はありません。
- ここで、単方向の関連付けのみがあり、この関係を維持しているのがセットである場合、逆に等しいをtrueにすると、その外部キーは決して設定されず、それらのアイテムはデータベースに設定された外部キー。
- Order.hbm.xml ファイルで多対1の関係を見て、逆を探した場合、実際には逆属性はありません。
- 常に子アイテムから設定されますが、多対多のコレクションがある場合は、どちら側からでも設定できます。