3

次の Nhibernate の問題で、一日中机に頭をぶつけています。

各銀行口座には、関連付けられたレートのセットが 1 つ (1 つだけ) あります。銀行口座テーブルの主キーである BankAccountID も外部キーであり、AccountRate テーブルの主キーです。

public class BankAccount
{
    public virtual int BankAccountId { get; set; }
    public virtual string AccountName { get; set;}
    public virtual AccountRate AccountRate {get;set;}
}

public class AccountRate
{
    public virtual int BankAccountId { get; set; }
    public virtual decimal Rate1 { get; set; }
    public virtual decimal Rate2 { get; set; }
}

BankAccount の次の HBM マッピングがあります。

<class name="BankAccount" table="BankAccount">
<id name ="BankAccountId" column="BankAccountId">
  <generator class="foreign">
    <param name="property">
      AccountRate
    </param>
  </generator>
</id>
<property name ="AccountName" column="AccountName" />
<one-to-one name="AccountRate" class="AccountRate" constrained="true" cascade="save-update"/>
</class>

AccountRate の場合は次のとおりです。

<class name="AccountRate" table="AccountRate">
<id name ="BankAccountId" column="BankAccountId">
  <generator class="native" />
</id>
<property name ="Rate1" column="Rate1" />
<property name ="Rate2" column="Rate2" />
</class>

データベースから既存の BankAccount オブジェクトを問題なく読み取ることができます。ただし、新しい BankAccount が作成されると、insert ステートメントは失敗します。

Cannot insert the value NULL into column 'BankAccountId'

問題は、子オブジェクトである AccountRate が最初に作成されることです。Parent から識別子をまだ取得していないため、挿入は失敗します。

BankAccount の AccountRate プロパティがコレクションである場合、次を使用できると言うのは正しいと思いますか?

Inverse=True

親を最初に強制的に挿入するため。

誰でもこれで私を助けることができますか?私は本当にコレクションを使用したくありません.これらのテーブル間には一方向の1対1の関係しかありません.

ありがとう

ポール

4

2 に答える 2

5

わかりました、私は問題を解決したと思います。私の問題は、共有された主キー値との古典的な 1 対 1 の関連付けのようです。答えは、ぐっすり眠ってから、 「Nhibernate in Action」の 192 ~ 193ページを参照することで見つかりました。

まず、修正が必要なエラーがいくつかありました。これには、クラスと HBM ファイルの両方の変更が必要でした。

まず、各クラスには他のクラス タイプのプロパティを含める必要があるため、BankAccount プロパティを AccountRate クラスに追加する必要がありました。

public class BankAccount 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual string AccountName { get; set;} 
    public virtual AccountRate AccountRate {get;set;} 
} 

public class AccountRate 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual decimal Rate1 { get; set; } 
    public virtual decimal Rate2 { get; set; } 
    Public virtual BankAccount BankAccount {get;set;}
} 

BankAccount HBM ファイルにもエラーがありました。ジェネレーター クラスを外部にすべきではありませんでした。それは AccountRate クラスにあったはずです。また、1 対 1 のリンクから制約を取り除く必要がありました。新しい BankAccount HBM ファイルは次のとおりです。

<class name="BankAccount" table="BankAccount">  
<id name ="BankAccountId" column="BankAccountId">  
  <generator class="native">  
</id>  
<property name ="AccountName" column="AccountName" />  
<one-to-one name="AccountRate" class="AccountRate" cascade="all"/>  
</class>  

次に、AccountRate HBM は、ジェネレーター クラスを foreign に設定し、クラス間の関係を完成させるために「1 対 1」タグを追加する必要があります。

<class name="AccountRate" table="AccountRate">          
<id name ="BankAccountId" column="BankAccountId">          
  <generator class="foreign">
        <param name="property">BankAccount</param>
  </generator>         
</id>          
<property name ="Rate1" column="Rate1" />          
<property name ="Rate2" column="Rate2" /> 
<one-to-one name="BankAccount" class="BankAccount" constrained="true" />       
</class>

この問題を検討するために時間を割いてくださったすべての方々に感謝します。それはすべて曲線の一部だと思います。

ポール

于 2010-05-10T11:20:53.677 に答える
0

これを回避する簡単な方法の 1 つは、BankAccountId を null 可能にすることです。NHibernate は BankAccount テーブルにヌル ID のレコードを挿入してから、ID を更新する必要があります。

過去に、null の代わりに正しい ID を使用して最初の挿入を行う方法を見つけました。残念ながら、私は一生、自分が何を変更したかを思い出すことができません。

于 2010-05-09T21:34:44.143 に答える