2011-05-13 39 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

相关问题