2009-04-21 7 views
1

私は1対多の関係を持っていますが、1対1の関係を持つインスタンスを1つしか取得しません。マッピングhbm.xml

私は、一生を通していくつかの所有者を持つクラスの車両を持っています。私はクラスをマップしてアセットを取得したいだけです。これを行うにはいくつかの方法がありますか?

問題はhbm.xmlファイルにあります。 1台の車両には一生を通して複数の所有者がいるかもしれませんが、私は最後の所有者だけを取得したいと考えています。 vehiculeId、ownerId、EndDateでフィルタリングする必要があります。私はvehicle.csにあるオブジェクトの所有者を資産でいっぱいにしたい。

私が書くとき:Vehicule v = VehiculeService.SearchVehicule(id);

v.Ownerに最後の車両の所有者が含まれている必要があります。

オーナーが日付に依存しているため、オーナーのIDを車両テーブルに保存できません。私は、例えば持つことができます。 車の所有者開始日終了日 1 1 2009年4月4日2009年4月10日 1 2 2009年5月10日NULL

私は資産を持って終了日でフィルタリングしなければならない。このような理由から

私は3つのテーブルを持っています:車両、所有者、所有者車両。問題は、現在の所有者にvehicle.csの参照が必要であるということです。そして、私はどのようにマッピングを行うのではありません。

ご協力いただければ幸いです。ありがとう

答えて

0

これをマップする簡単な方法は、多対1の関係にして、現在の所有者のIDを車両テーブルに格納することです。私はこれがスキーマの変更かもしれないと理解します。

これを騙す方法の1つは、本質的に車両テーブルとなるビューを作成し、現在のオーナーIDをプルすることです。この方法でスキーマを変更する必要はなく、表の代わりにビューにマップします。

この場合、独自のローダを定義することはできますが、もう1つの選択肢がありますかどうかはわかりません。

編集

私はあなたの予測を理解しています。最も簡単な方法は、スキーマとアプリケーションを修正して、この追加の列を追加してビューを作成する方法です。したがって、たとえば

select vehicle.*, owner.ownerid 
from vehicle 
inner join owner 
    on owner.vehicleid=vehicle.vehicle 
and owner.enddate is null 

ここでは、現在の所有者には終了日がNULLと仮定します。これで、テーブルの代わりにビューにマッピングするマッピングが変更されました。はい、これはハックですが動作します。

オーナーがnHibernate内にマップされる必要があるとしますか?もう1つのオプションは、終了日がnullの場所をフィルタリングするために、所有者のクラスマッピングにwhereフィルタを追加することです。

また、所有者をすべてロードして、現在の所有者を定義するビジネスルールをアプリケーション層にプッシュすることもできます。

あなたは(春またはDetachedCriteriaを)基準を使用することができます
public Owner CurrentOwner 
{ 
    get 
    { 
     return _owners.Find(o=>o.EndDate==DateTime.Min); //Or null if your using a nullable datetime 
    } 
    set 
    { 
     CurrentOwner.EndDate=DateTime.Now; 
     _owners.Add(value); 
    } 
} 

}

+0

基準ベースのクエリは、次のようになります。私は、例えば持つことができます。 車の所有者開始日終了日 1 1 2009年4月4日2009年4月10日 1 2 2009年5月10日NULL資産 –

0

検索を行うときに追加の値を制限するオブジェクト:あなたのオブジェクトは、次のようになります。

0

ビジネス層でこの参照を維持し、それを多対1の関係としてマップすることをお勧めします。つまり、コード内でこの参照を明示的に設定するということです。これにより、現在の所有者による車両を簡単に見つけることができます。

例:

<class name="Vehicle"> 
    <map name=AllOwners" > 
    ... 
    </map> 

    <many-to-one name="CurrentOwner" ...> 
</class> 

public class Vehicle 
{ 
    IList<Owner> AllOwners { get; private set; } 
    Owner CurrentOwner { get; set; } 
} 

public void SetNewOwner(Vehicle v, Owner o) 
{ 
    v.AllOwners.Add(o); 
    v.CurrentOwner = o; 
} 
+0

すでに私が持っている私は、終了日でフィルタリングしなければならない。このため 私のクラスの車両の所有者への参照を持っているので、vehicle.ownerが私のコードのすべての面に表示されます。 私はビークルv = VehicleService.Search(id)を書く。 どのようにv.Vehicleがいっぱいですか? –

+0

あなたは「どのようにv.AllOwnersがいっぱいですか?」という意味ですか? NHibernateはPersistentBagか何かを作成し、それをプロパティの(私的な)セッターに割り当てます。まだ初期化されていない可能性があるので、プロパティのセッターでリストにアクセスすることはできません。 –

0

あなたの関係は、所有者が複数の車両

私は別の車と所有者を維持し、他の企業で彼らの関係を管理するのを所有することができ、実際に多対多の

です 別の言葉では、3つのテーブルが必要です

あなたの質問が変更されたか、答え:

+0

私は既に3つのテーブルを持っています:Vehicle、OwnerそしてOwnerVehicle。問題は、現在の所有者にvehicle.csの参照が必要であるということです。そして、私はどのようにマッピングを行うのではありません。 –

0

私はNHibernate eagerが "Owner"プロパティを自動的にロードすることはできません。しかし、車両の現在の所有者を取得するためのクエリを書くことができるはずです。既にVehiculeServiceのVehicleレポジトリ/サービスを持っているようです。私はGetCurrentOwner()のような1つのパラメータ、すなわち車両のIDを取る方法を追加します。次に、Vehicle.Ownerプロパティで独自のIDを渡してこのメ​​ソッドを呼び出します。所有者は、日付に依存しているため、私は車のテーブルの上に所有者のIDを格納することはできません

session.CreateCriteria(typeof(Owner)) 
    .CreateCriteria("OwnedVehicles") // Property path to the OwnerVehicle join table 
     .Add(Expression.IsNull("EndDate")) 
     .CreateCriteria("Vehicle") 
      .Add(Expression.IdEq(id)) 
      .UniqueResult<Owner>(); 
関連する問題