2011-08-09 4 views
0

トリッキーな問題 - 私にご負担ください。どんな助けでも大歓迎です。マルチプル "ロール"を使用したサブクラスマッピング

私はテーブル/クラスの連絡先(PK Id)と2つの派生したクライアントと債務者(PKとFK ContactId)を持っています。第4テーブルのCaseには、DebtorとClientへの外部キー(以下のマッピング)があります。

最初はすべて正常に機能しました。しかし、その後私は同じContactがあるケースではクライアント、別のケースではDebtorであるデータをヒットしました。これらはSession.Query<Case>().Fetch(c => c.Debtor).Fetch(c => c.Client) のようなものNHibernateのクエリで読まれている場合

NHibernate.WrongClassException 
    "Object with id: {someGuid...} was not of the specified subclass: Client 
    (loading object was of wrong class [Debtor]) 

があり、セッション最初のレベルのキャッシュは、それがIDとSQLの結果セットからのデータの読み出しを回避しようとすることで、レコードを認識しているように思えます。もちろん、キャストNHは再利用に失敗すると考える。

残念ながら、DBスキーマを変更することはできません。それはレガシーシステムです。 (スキーマは正常であり、IMOはクリーンです)

重要かどうかわかりません:クラスContactは抽象ではありません。クライアントでもなく債務者でもない連絡先が使用されています。

これらの複数の役割を持つ連絡先でこれを動作させる可能性はありますか?前もって感謝します。

public partial class ContactMap : ClassMap<Contact> 
{ 
    public ContactMap() 
    { 
    Id(x=>x.Id).GeneratedBy.Guid(); 
    Map(x=>x.FirstName); 
    Map(x=>x.Name1).Not.Nullable(); 
     ... 
    } 
} 
public class DebtorMap : SubclassMap<Debtor> 
{ 

    public DebtorMap() 
    { 
     KeyColumn("ContactID"); 
     Table("[dbo].[Debtor]"); 
     Map(x => x.MaritalStatus); 
     ... 
    } 
} 

public partial class ClientMap : SubclassMap<Client> 
{ 

    public ClientMap() 
    { 
     KeyColumn("ContactID");    
     Map(x => x.ClientNo).Not.Nullable(); 
     ... 
    } 
} 

public partial class CaseMap : ClassMap<Case> 
    public CaseMap() 
    { 
     ... 
     References<Client>(x=>x.Client) 
     References<Debtor>(x=>x.Debtor) 
     ... 
    }  
+0

:役割は、次のようになり見ます時間。 – Firo

+0

私はあなたがスキーマを変更することはできないが、スキーマにビューを追加することはできますか? – eulerfx

答えて

0

スキーマにビューを追加することができる場合は、クライアントレコードと債権レコードの両方を結合するロールというビューを作成できます。その後、役割を表すために、あなたのオブジェクトモデルを変更することができます。Contactテーブルは今、これは動作するはずクライアントと債務者のテーブルにPKを共有ん

class Contact 
{ 
    public virtual Guid Id { get; set; } 
    public virtual string FirstName { get; set; } 
    public virtual ICollection<Role> Roles { get; private set; } 
} 

class Role 
{ 
    public virtual Guid Id { get; set; } 
} 

class Client : Role 
{ 
    public virtual string ClientNo { get; set; } 
} 

class Debtor : Role 
{ 
    public virtual string MaritalStatus { get; set; } 
} 

class ContactMap : FluentNHibernate.Mapping.ClassMap<Contact> 
{ 
    public ContactMap() 
    { 
     Table("dbo.Contacts"); 
     Id(x => x.Id).GeneratedBy.GuidComb(); 
     Map(x => x.FirstName); 
     HasMany(x => x.Roles) 
      .KeyColumn("ContactId") 
      .Not.LazyLoad() 
      .Fetch.Join(); 
    } 
} 

class RoleMap : FluentNHibernate.Mapping.ClassMap<Role> 
{ 
    public RoleMap() 
    { 
     Table("dbo.Roles"); 
     Id(x => x.Id).GeneratedBy.GuidComb(); 
     this.Polymorphism.Implicit(); 
    } 
} 

class ClientMap : FluentNHibernate.Mapping.SubclassMap<Client> 
{ 
    public ClientMap() 
    { 
     Table("dbo.Clients"); 
     KeyColumn("Id"); 
     Map(x => x.ClientNo); 
    } 
} 

class DebtorMap : FluentNHibernate.Mapping.SubclassMap<Debtor> 
{ 
    public DebtorMap() 
    { 
     Table("dbo.Debtors"); 
     KeyColumn("Id"); 
     Map(x => x.MaritalStatus); 
    } 
} 

ので。オブジェクトが同じで、2つの異なる種類がありカントので、それは、オブジェクト・アイデンティティともOOP-プリンシパルについてのNHの仮定に反するので、私は、ハックせずにその可能性を考えていけない

create view dbo.Roles as 

select 
    Id, 
    ContactId 
from dbo.Clients 

union all 

select 
    Id, 
    ContactId 
from dbo.Debtors 
関連する問題