11

テーブル Transactions を含む既存のデータベースがあります。各トランザクションが最終的に 1 つのレコードしか持たない TransactionSequence という新しいテーブルを追加しました。シーケンス テーブルを使用して、特定のアカウントのトランザクションをカウントしています。これを、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>

どんな助けでも大歓迎です...

4

2 に答える 2

15

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" />

これは、あなたがやりたいことをするはずです。プロパティ参照に注意してください。

あなたが投稿する次の質問は、1 対 1 の関連付けで遅延読み込みを行う方法を尋ねることです。答えは、できません... できますが、おそらくうまくいかないでしょう。問題は、シーケンス テーブルに外部キーがあることです。つまり、ターゲットが存在するかどうかを確認するために、nhibernate がデータベースにアクセスする必要があります。次に、constrained="true/false" をいじってみて、1 対 1 の関連付けを遅延ロードするように説得できるかどうかを確認します。

全体として、それはあなたの時間を完全に無駄にすることになります。

次のいずれかをお勧めします。

  1. 2 つの多対 1 関連付けがあります。
  2. 反対側のコレクションと多対 1 の関連付けを行います。

これにより、長期的には多くの頭痛が解消されます。

于 2008-10-28T21:05:03.860 に答える
2

私の状況では、<join table>マッピングが最適であることがわかりました。2 番目のテーブルから取得したプロパティが null 許容型であることを確認する必要がありました。そうしないと、何も変更されていなくても、保存時に挿入が実行されます。2 番目のテーブルの遅延読み込みは必要なかったので、これはうまく機能します。多対 1 のマッピングを組み合わせて機能させることができたと確信していますが、直感的ではなく、結合テーブル オプションよりも複雑に思え<join table>ますが、NHibernate 2.0 以降でのみ使用できます。

于 2008-10-29T12:58:52.717 に答える