2010-12-07 9 views
5

NHibernateでこの関係をモデル化する必要があります(トピックをそのまま残すためにコードを単純化しました) - 従業員はaccountmanagerになることができます):間違った(ブラウンフィールドの)データベーススキーマと1対1の関係をマッピングする

テーブル従業員(ID、番号、名前) テーブルEmployeeIsAccountManager(番号、MaxAllowedDiscount)

代わりテーブル従業員を指すテーブルEmployeeIsAccountManagerのid外部キーを有することが、私は、従業員の数値列を有しますEmployeeIsAccountManagerテーブルのNumberカラムを指すテーブル。

これをNHibernateでどのようにマップするのですか? EmployeeIsAccountManagerクラスマッピングで外部ジェネレータを使用しようとしましたが、外部生成値としてNumberを使用すると、Numberの代わりにIdであるEmployeeのIDにマップされます。私は、組成物を使用するために私のクラスをモデル化:

public class Employee 
{ 
    public virtual int Id { get; set; } 
    public virtual short Number {get; set; } 
    public virtual string Name {get; set; } 
    public virtual AccountManager AccountManager { get; set; } 
} 

public class AccountManager 
{ 
    public virtual short Number { get; set; } /*needed because of ID only?*/ 
    public virtual decimal MaxAllowedDiscount { get; set } 
} 

私は(多対1 1対1、外国ジェネレータ)多くのことを試してみたが、これはで行うことができる場合、私は把握することはできませんNHibernate。 btw:私はクラス、マッピングなどを変更することができますが、Brownfieldのステータス(2百万行以上のコードを持つ古いアプリケーション、ほぼ1000のフォーム)のためにテーブル構造を変更できません。

ご協力いただきありがとうございます。 Ted

+1

プロパティ-refのマッピング属性を見上げて... – JulianM

答えて

0

あなたの質問は私がクラスAccountManagerをEmployeeのサブクラスとしてマッピングすることができますし、あなたがしたいことを実行できるようになります。あなたのマッピングで気づかなければならない2つの点があります:

  1. Employeeテーブルのnumberプロパティは、使用するためにAccountManagerのforeingキーの一意の種類でなければなりませんあなたが新しいアカウントマネージャーを挿入しようとすると、人のテーブルにレコードを挿入し、その後、人のIDをAccouの番号の列に割り当てますntManagerはあなたが必要とする休憩です。
  2. 同じ理由でmany-to-oneの関係をマッピングすることはできません。 AccountManagerのNumberプロパティは主キーですか?ユニークです? NHibernateは主キーなしでは動作できませんので、その関係を動作させるためには、AccountManagerのIDプロパティをIdカラムとして指定する必要があります。

私の最後のオプションは、従業員クラス をAccountManagerテーブルにマップします。ここでは、必要な値を取得するカスタム選択を指定できます。プロパティMaxAllowedDiscountを仮定しますが、これにはいくつかの制限があります。数式でプロパティをマップすると、このプロパティは挿入できません。更新されません。

ご質問がある場合は、 お手数ですがお手数ですがお手数ですが、

+0

私が必要として、私はこれをマッピングすることができるように私は、データベース・スキーマに追加の冗長なフィールドを追加しました。フィールド自体はデータベース内のトリガーによって管理されます。 – TedOnTheNet

0
public class Employee 
{ 
    public virtual short Number 
    { 
     get { return (AccountManager == null) ? 0 : AccountManager.Number; } 
     set 
     { 
      if (AccountManager == null) 
       AccountManager = new AccountManager(); 
      AccountManager.Number = value; 
     } 
    } 
    public virtual AccountManager AccountManager { get; set; } 
} 

またはGeneratedBy.Assingedと()

public class Employee 
{ 
    public Employee() 
    { 
     AccountManager = new AccountManager(); 
    } 

    public virtual AccountManager AccountManager 
    { 
     get; 
     set { value.Parent = this; _accountManager = value; } 
    } 

    public class AccountManager 
    { 
     Internal protected virtual Employee Parent { get; set; } 

     protected virtual short Number { get { return Parent.Number; } set { } } /*needed because of ID only?*/ 
     public virtual decimal MaxAllowedDiscount { get; set } 
    } 
} 
関連する問題