2011-08-09 36 views
0

一個棘手的問題 - 請耐心等待。任何幫助不勝感激。Multipe「角色」的子類映射

我有一個表/類聯繫人(PK Id)和兩個派生的客戶端和債務人(PK和FK ContactId)。第四個表格Case具有債務人和客戶端的外鍵(下面的映射)。

一開始一切正常。但後來我碰到了一些數據,其中一個聯繫人在一個案例中是客戶,而在另一個案例中是債務人。如果這些都在一個NHibernate的查詢關鍵詞,比如Session.Query<Case>().Fetch(c => c.Debtor).Fetch(c => c.Client) 閱讀有一個

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

好像會話一級緩存是認識的記錄由它的ID,並試圖避免讀取從SQL數據結果集。當然,演員NH認爲必要的重用失敗。

不幸的是,更改數據庫架構不是一個選項。這是一個遺留系統。 (一個模式是好的,乾淨的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

我不認爲它可能沒有黑客,因爲它違背NH的有關對象的身份並OOP校長的假設,因爲對象不能同時是2種不同類型的時間。 – Firo

+0

我知道你不能改變模式,但是你可以添加一個模式的視圖嗎? – eulerfx

回答

0

如果您可以向模式添加視圖,則可以創建一個名爲角色的視圖,它將客戶端和債務人記錄聯合起來。然後你可以改變你的對象模型來表示角色:

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); 
    } 
} 

由於接觸表不現在與客戶和債務人表這應該共享一個PK。角色視圖會是這個樣子:

create view dbo.Roles as 

select 
    Id, 
    ContactId 
from dbo.Clients 

union all 

select 
    Id, 
    ContactId 
from dbo.Debtors