2011-05-13 90 views
4

我在Fluent NHibernate中遇到了繼承問題。流利的NHibernate集合每個子集的表

我已經設法讓Table-Per-Subclass工作,但是我無法獲得基類的集合來工作。它正在尋找一個我沒有的基礎表。

這裏是我的架構:

User(Id, Name, Email) 

User_Account_Password(Id, UserId, PasswordHash, Salt) 

User_Account_Facebook(Id, UserId, FacebookId) 

這裏是我的對象模型:

public class User 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Email { get; set; } 
    public virtual IList<UserAccount> Accounts { get; set; } 
} 

public abstract class UserAccount 
{ 
    public virtual int Id { get; set; } 
    public virtual User User { get; set; } 
} 

public class UserAccountPassword : UserAccount 
{ 
    public virtual string PasswordHash { get; set; } 
    public virtual string Salt { get; set; } 
} 

public class UserAccountFacebook : UserAccount 
{ 
    public virtual long FacebookId { get; set; } 
} 

這裏的映射文件:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Table("user"); 

     Id(x=>x.Id); 

     Map(x=>x.Name); 
     Map(x=>x.Email); 

     //This is the collection I am having trouble with. 
     HasMany(x=>x.Accounts) 
     .KeyColumn("UserId") 
     .Cascade.SaveUpdate() 
     .Not.LazyLoad(); 
    } 
} 

public class UserAccountMap : ClassMap<UserAccount> 
{ 
    public UserAccountMap() 
    { 
     Id(x=>x.Id); 

     References(x => x.User) 
      .Column("UserId"); 
    } 
} 

public class UserAccountPasswordMap : SubclassMap<UserAccountPassword> 
{ 
    public UserAccountPasswordMap() 
    { 
     Table("user_account_password"); 

     Map(x=>x.PasswordHash); 
     Map(x=>x.Salt); 
    } 
} 

public class UserAccountFacebookMap : SubclassMap<UserAccountFacebook> 
{ 
    public UserAccountFacebookMap() 
    { 
     Table("user_account_facebook"); 

     Map(x=>x.FacebookId); 
    } 
} 

這將正常工作,如果我有在用戶收集n個Facebook帳戶和一組密碼帳戶。然而,這個想法是讓這些鏈接到用戶,以便我們以後可以讓人們不使用Facebook或添加Facebook作爲登錄方法,但保持相同的帳戶。

我得到的錯誤是「表myschema.useraccount」不存在。這表明它忽略了UserAccount是抽象的事實..

這似乎是根據http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses做Table-Per-Subclass的推薦方式,但感覺就像我錯過了一些東西。

任何想法?

回答

3

每個子類的表是反直覺的名稱,因爲基類(或超類)也需要表(請參閱NH documentation)。如果useraccount表不存在,NH會拋出異常。

如果用傳統的數據庫和基礎類工作表中不可用,那麼你可以使用table-per-concrete-class或所謂的聯盟 - 子類的映射:

public class UserAccountMap : ClassMap<UserAccount> 
{ 
    public UserAccountMap() 
    { 
     Id(x => x.Id).GeneratedBy.Assigned(); // cannot use identity generator with union-subclass mapping 

     References(x => x.User) 
      .Column("UserId"); 

     this.UseUnionSubclassForInheritanceMapping(); // tell FNH that you are using table per concrete class mapping 
    } 
} 

編輯: UserAccount表必須存在於數據庫模式使用每個子表的映射。該表必須包含兩列:Id和UserId。

+0

感謝您的回答。我將如何更改當前的模式以使用Table-per-subclass?你是否也認爲這是一個好策略? – 2011-05-14 15:02:10

+0

請參閱編輯答案。我經常使用每個子類的表(多態查詢和集合),我還沒有遇到任何問題。但這取決於你的需求,一切都有優點和缺點...... – 2011-05-14 15:23:00

相關問題