Fluent NHibernate 集合每个子类表

发布于 2024-11-07 17:21:19 字数 2332 浏览 3 评论 0原文

我在 Fluent NHibernate 中的继承方面遇到问题。

我之前已经设法让 Table-Per-Subclass 工作,但我无法让基类的集合工作。它正在寻找一个我没有的基类表。

这是我的架构:

用户(ID、姓名、电子邮件)

User_Account_Password(Id、UserId、PasswordHash、Salt)

User_Account_Facebook(ID,用户ID,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 但感觉我错过了一些东西。

有什么想法吗?

I am having trouble with inheritance in Fluent NHibernate.

I have managed to get Table-Per-Subclass working before but I can't get a collection of the baseclass to work. It is looking for a table for the base class which I don't have.

Here's my schema:

User(Id, Name, Email)

User_Account_Password(Id, UserId, PasswordHash, Salt)

User_Account_Facebook(Id, UserId, FacebookId)

Here's my object model:

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

Here's the mapping files:

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

This would work fine if I had on user a collection of Facebook accounts and a collection of password accounts. However, the idea is to make these link to the user so that we can later allow people to not use facebook or to add facebook as a login method but to keep the same account.

The error I'm getting is "Table myschema.useraccount" does not exist. Which suggests it is ignoring the fact UserAccount is abstract..

This seems to be the recommended way to do Table-Per-Subclass according to http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses but it feels like I'm missing something.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

℉絮湮 2024-11-14 17:21:19

Table-per-subclass 是一个反直觉的名称,因为基类(或超类)也需要一个表(参见 NH 文档)。如果 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。

Table-per-subclass is anti-intuitive name because a table is required for the base class (or super class) as well (see NH documentation). If the useraccount table does not exist, NH throws exception as in your case.

If you work with legacy database and a base class table is not available, then you could use table-per-concrete-class or so called union-subclass mapping:

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

EDIT:
UserAccount table must be present in database schema to use table-per-subclass mapping. The table must contain two columns: Id and UserId.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文