Fluent NHibernate Collection Table-Per-Subclass - PullRequest
4 голосов
/ 13 мая 2011

У меня проблемы с наследованием в 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 является абстрактным ..

Кажется, это рекомендуемый способ сделать Table-Per-Subclass согласно http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses, но мне кажется, что я что-то упустил.

Есть идеи?

1 Ответ

3 голосов
/ 14 мая 2011

Таблица для каждого подкласса является антиинтуитивным именем, потому что таблица требуется и для базового класса (или суперкласса) (см. Документацию NH ). Если таблица useraccount не существует, NH выдает исключение, как в вашем случае.

Если вы работаете с устаревшей базой данных, а таблица базового класса недоступна, вы можете использовать таблица для каждого конкретного класса или так называемое сопоставление подкласса объединения:

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 должна присутствовать в схеме базы данных, чтобы использовать отображение таблицы на подкласс. Таблица должна содержать два столбца: Id и UserId.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...