流畅的NHibernate集合表每子类

时间:2011-05-13 14:13:23

标签: c# inheritance orm fluent-nhibernate

我在Fluent 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);
    }
}

如果我在用户上拥有一组Facebook帐户和一组密码帐户,这样可以正常工作。但是,我们的想法是将这些链接发送给用户,以便我们以后可以允许人们不使用Facebook或将Facebook添加为登录方法,但保留相同的帐户。

我得到的错误是“表myschema.useraccount”不存在。这表明它忽略了UserAccount是抽象的事实..

这似乎是根据http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses进行Table-Per-Subclass的推荐方法,但感觉我错过了一些东西。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

Table-per-subclass是反直觉的名称,因为基类(或超类)也需要一个表(参见NH documentation)。如果useraccount表不存在,NH会像你的情况一样抛出异常。

如果您使用旧数据库并且基类表不可用,那么您可以使用table-per-concrete-class或所谓的union-subclass映射:

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表必须存在于数据库模式中才能使用table-per-subclass映射。该表必须包含两列:Id和UserId。