2009-04-01 22 views
9

私は、これは簡単な質問ですが、次の点を考慮して確信しているとして、外部キー列をマップする方法: 次のように私は、会社と部門間の参照を持っている:流暢NHibernateは - プロパティ

public class Company { 
    public Guid ID { get; set; } 
    public Sector Sector { get; set; } 
    public Guid SectorID { get; set; } 
} 

public class Sector { 
    public Guid ID { get; set; } 
    public string Name { get; set; } 
} 

[OK]をクリックします。私が望むのは、私が行くとCompanyオブジェクトのSectorIDが移入された後です。

(new Company()).Sector = new Sector() { Name="asdf" } 

となります。

私が使用しているマッピングは、CompanyテーブルのSector_Idと呼ばれる追加の列をデータベースに作成しますが、Companyのプロパティとしては使用できません。私は、SectorIDプロパティを埋めたいと思っています。

私は現在CompanyMapで使用しているマッピングが

References(c => c.Sector).Cascade.All(); 

誰がどんな考えを持っていますか?


ご回答ありがとうございます。私は(プロパティと同じであるか、またはMap(x => x.SectorID, "Sector_Id")を設定するには、列の列名を設定する2番目のオプションを行う場合 は、悲しいことに、私はエラーを取得する:

System.IndexOutOfRangeException:カウントでこのSqlParameterCollectionのために無効なインデックス7 = 7.

私は最初のオプションを実行する必要があるかもしれませんが、SectorIDを呼び出すと、セクター自体がdbから取得されるため、追加のクエリが発生することが懸念されます。ほんの少しの手間)

これには簡単な答えはありませんが、私は驚いています。


WOW!私は

public virtual Guid SectorID 
{ 
    get { return Sector.ID; 
} 

を使用する場合 は、NHibernateは組織のクエリでSector_id列が実際にSector.IDと同じものであることを知ってくれているし、それはボンネットの下に、これを返します。遅延ロードであっても、追加のクエリを送信しません。私は感銘を受けて!


フォローアップとして...実際には、オブジェクト内の外部キー列をマップできるように、Hibernateは書かれていないようです。これはウェブのフロントエンドで少し痛みがあるかもしれませんが、これは本当にオブジェクトの懸念ではなく、永続性の懸念事項なので意味があります。 私はasp.net MVCを使用しており、名前の入力ボックス(ContactIDではなく)、新しいtexbox内のIDとの新規連絡先を入力し、これを適用するカスタムモデルバインダーを作成しました。モデルの特性これは、Webフロントエンドのドロップダウンリストで問題を回避します。誰かが興味があれば、コードを投稿します。

答えて

2

2つの考え:まず第一に、これはあなたが望むものを達成するようなものではないでしょうか?

public class Company { 
    public Guid ID { get; set; } 
    public Sector Sector { get; set; } 
    public Guid SectorID { 
     get { return Section.ID; } 
     // Really not sure what behavior your setter should have here; Maybe it shouldn't even have one? 
     set { Sector = new Sector { ID = value }; } 
    } 
} 

第二に、あなたはマッピングはDBの列を作成したと言うSector_Idと呼ばれ、セクタIDという名前の作成した列に加えて、ということでしょうか?その場合は、正しい名前を使用するように列名を変更できます(here's the documentation for mappings、「列名の指定」を参照)。

また、SectorIDプロパティ(「Map(x => x.SectorID、 "Sector_Id")」)をマッピングしていますか?

2

SteveあなたはPOCOクラスのForeignKeyプロパティは必要ありません。

たとえば、アーティクルの作成者のIDを取得しようとすると、結合選択が実行されません。

VAR authorID = Article.Author.ID

13

これは容易式プロパティを用いて行われます。

public class Company { 
    public virtual Guid Id { get; set; } 
    public virtual Guid? SectorId { get; set; } 
    public virtual Sector Sector { get; set; } 
} 

public class CompanyMap : ClassMap<Company> { 
    public CompanyMap() { 
    Id(x => x.Id); // Maps to a column named "Id" 
    References(x => x.Sector); // Maps to a column named "Sector_id", unless you change the NHibernate default mapping rules. 
    Map(x => x.SectorId).Formula("[Sector_id]"); 
    }  
} 

これは、あなたが望むように正確に動作するはずです。 Companyが新規の場合、SectorIdはnullになります。 CompanyがDBからフェッチされると、SectorIdには指定された数式値が入力されます。 SectorIdはプロパティとして公開されているため、Webドロップダウンなどの処理には本当に便利です。保存する際には、「実際の」関連付けをバインドする必要があります。 SectorIdがフォームで選択されたと仮定すると...

using (var txn = session.BeginTransaction()) { 
    // Set the FK reference. 
    company.Sector = session.Load<Sector>(company.SectorId); 
    // Save the new record. 
    session.Save(company); 
    // Commit the transaction. 
    txn.Commit(); 
} 
+0

私が得たエラーを解決するためのポイントを示しますが、これは完全に直感的ではないようです。それは、プロパティとしてFK IDと関連するオブジェクトインスタンスの両方を持つような一般的なシナリオを処理できない場合、NHibernateの設計上の問題のようです。 –