2番目のテーブルデータがnullになる可能性があるNHibernateの1対1マッピング
-
05-07-2019 - |
質問
テーブルTransactionsを含む既存のデータベースがあります。 TransactionSequenceと呼ばれる新しいテーブルを追加しました。各テーブルには、最終的に1つのレコードしかありません。シーケンステーブルを使用して、特定のアカウントのトランザクションをカウントしています。 TransactionSequenceにTransactionIdのプライマリキーがある1対1マッピングとしてこれをマッピングしました。
制約は、トランザクションテーブルの代わりにトリガーがあり、キャンセルまたはポストされたトランザクションの更新を許可しないことです。
したがって、シーケンスが計算され、トランザクションが保存されると、NHibernateは 'UPDATE Transaction SET TransactionId =? WHERE TransactionId =? 'しかし、これはトリガーのために失敗します。新しいTransactionSequenceテーブルが挿入されたときにNHibernateがTransactionテーブルを更新しないようにマッピングを構成するにはどうすればよいですか?
トランザクションマッピング:
<class name="Transaction" table="Transaction" dynamic-update="true" select-before-update="true">
<id name="Id" column="ID">
<generator class="native" />
</id>
<property name="TransactionTypeId" access="field.camelcase-underscore" />
<property name="TransactionStatusId" column="DebitDebitStatus" access="field.camelcase-underscore" />
<one-to-one name="Sequence" class="TransactionSequence" fetch="join"
lazy="false" constrained="false">
</one-to-one>
</class>
そしてシーケンスマッピング:
<class name="TransactionSequence" table="TransactionSequence" dynamic-update="true">
<id name="TransactionId" column="TransactionID" type="Int32">
<generator class="foreign">
<param name="property">Transaction</param>
</generator>
</id>
<version name="Version" column="Version" unsaved-value="-1" access="field.camelcase-underscore" />
<property name="SequenceNumber" not-null="true" />
<one-to-one name="Transaction"
class="Transaction"
constrained="true"
foreign-key="fk_Transaction_Sequence" />
</class>
ご協力いただければ幸いです...
解決
nhibernateでの1対1のマッピングは、思ったとおりには機能しません。 2つのクラスがあり、対応するテーブルに永続化されると同じ主キーを持つように設計されています。
ただし、機能させることはできますが、きれいではありません。次に、いくつかの選択肢を提供する方法を示します。
トランザクションhbmlで:
<one-to-one name="Sequence" class="TransactionSequence" property-ref="Transaction"/>
シーケンスhtml:
<many-to-one name="Transaction" class="Transaction" column="fk_Transaction_Sequence" />
これはあなたがやりたいことを行うべきです。 property-refに注意してください。
次に投稿する質問は、1対1の関連付けで遅延読み込みをどのように行うかを尋ねることです。答えは、あなたは...できないということです。しかし、あなたはできますが、おそらくうまくいきません。問題は、シーケンステーブルに外部キーがあることです。つまり、nhibernateはデータベースにアクセスして、ターゲットが存在するかどうかを確認する必要があります。次に、constrained = <!> quot; true / false <!> quot;で遊んでみてください。 1対1の関連付けを遅延ロードするように説得できるかどうかを確認します。
全体として、それはあなたの時間の全体的な無駄になります。
次のいずれかをお勧めします:
- 2つの多対1の関連付けがあります。
- 反対側のコレクションと多対1の関連付けを行います。
これにより、長い目で見れば頭痛の種が大幅に減ります。
他のヒント
私の状況では、<join table>
マッピングが最適に機能したことがわかります。 2番目のテーブルから取得したプロパティがnull許容型であることを確認する必要がありました。そうしないと、何も変更されていない場合でも保存時に挿入されます。 2番目のテーブルの遅延読み込みは必要なかったので、これはうまく機能します。多対1のペアのマッピングを機能させることができたはずですが、直感的ではなく、テーブルの結合オプションよりも複雑に見えますが、<=>はNHibernate 2.0以降でのみ使用可能です。