Проблемы с автоматическим отображением домена в режиме гибернации

Пытаюсь разобраться с автоматическим картированием. У меня возникла проблема при попытке автоматического сопоставления моего домена и создания базы данных. Я уверен, что это что-то простое, я делаю не так.

Проблема в том, что генерируются правильные таблицы, но в сгенерированных таблицах присутствует только поле ID из базового класса, ни одно из других полей внутри сущностей не генерируется.

BaseEntity находится в пространстве имен, отличном от сущностей.

Я не уверен, что делать дальше, есть идеи?

Вот моя конфигурация сопоставления:

public static ISessionFactory CreateSessionFactory()
{
  return _sessionFactory = Fluently.Configure()
    .Database(ConfigureDatabase())
    .Mappings(m => m.AutoMappings.Add(CreateMappings()))
    .ExposeConfiguration(BuildSchema)
    .BuildSessionFactory();
}

private static IPersistenceConfigurer ConfigureDatabase()
{
  return MsSqlConfiguration
    .MsSql2008.ShowSql()
    .ConnectionString(c => c.FromAppSetting("MSSqlConnectionString"))
    .ProxyFactoryFactory<ProxyFactoryFactory>();
}

private static AutoPersistenceModel CreateMappings()
{
  return AutoMap.AssemblyOf<Organisation>(new AutomappingConfig())
    .Conventions.Add<CascadeConvention>();
}

private static void BuildSchema(Configuration config)
{
  new SchemaUpdate(config)
    .Execute(false,true);
}

Вот мой autoMappingConfig

public class AutomappingConfig : DefaultAutomappingConfiguration
{
  public override bool ShouldMap(Type type)
  {
    return type.Namespace == "Domain.Model" && type.IsClass;
  }
}

И все мои сущности наследуют этот базовый класс:

public class BaseEntity<T> where T : BaseEntity<T>
{
  public virtual int Id { get; set; }
}

И пример объекта:

public class Contact : BaseEntity<Contact>, IAggregateRoot
{
  public virtual String Name { get; set; }
  public virtual Organisation Organisation { get; set; }
}

person gdp    schedule 18.04.2011    source источник
comment
возможно ли, что другие ваши классы не находятся в той же сборке, что и «Организация»?   -  person J. Ed    schedule 18.04.2011
comment
@sJhonny они точно находятся в одной сборке.   -  person gdp    schedule 18.04.2011
comment
Какую версию FNH и NH вы используете?   -  person Cole W    schedule 28.04.2011


Ответы (2)


BaseEntity находится в пространстве имен, отличном от сущностей.

Возможно, вы захотите поместить их в одно и то же пространство имен. Также вы можете прокомментировать чек, который вы указали выше:

return type.Namespace == "Domain.Model" && type.IsClass;

Вышеупомянутое утверждение может быть причиной того, что вы сопоставляете только свои базовые классы. В каком пространстве имен находится ваш базовый класс и в каком пространстве имен находится одна из ваших примеров сущностей?

Когда я сталкиваюсь с подобными проблемами, я пытаюсь их упростить, пока не выясню, что вызывает мои проблемы.

Изменить:

После дальнейших исследований я думаю, вам нужно использовать следующее:

.IgnoreBase(typeof(BaseEntity<>));  

Таким образом, ваш код выше будет изменен на:

private static AutoPersistenceModel CreateMappings()
{
  return AutoMap.AssemblyOf<Organisation>(new AutomappingConfig())
    .Conventions.Add<CascadeConvention>()
    .IgnoreBase(typeof(BaseEntity<>));
}

Это выдержка из FNH Wiki:

Мы добавили вызов IgnoreBase, который просто указывает автомату игнорировать класс Entity; вы можете связать этот вызов столько раз, сколько потребуется.

С этим изменением мы получили желаемое отображение. Сущность игнорируется, что касается Fluent NHibernate, и все свойства (в нашем случае Id) обрабатываются так, как если бы они были в определенных подклассах.

person Cole W    schedule 24.04.2011
comment
@cole w извините за задержку с ответом, я пробовал то, что вы предложили, но я все равно получаю тот же результат, таблица создается для каждого класса, но только с полем Id в. - person gdp; 28.04.2011
comment
@geepie, взгляните на мою правку выше и посмотрите, поможет ли это вам. Я смог продублировать то, что вы видели, и это исправило это для меня. - person Cole W; 28.04.2011
comment
@geepie Также всякий раз, когда вы пытаетесь восстановить свою схему, я сначала удаляю старые таблицы из вашей базы данных. У меня возникли проблемы с этим, если я не удалил их сначала. - person Cole W; 28.04.2011
comment
Я согласен, что IgnoreBase, вероятно, то, что нужно, а не IncludeBase. Я не могу представить, чтобы @geepie хотел, чтобы его схема БД включала отношения наследования между BaseEntity и его подклассами. Нецелесообразно объединять каждую таблицу в одну, которая содержит все идентификаторы. - person Daniel Schilling; 28.04.2011
comment
@Cole W, спасибо за правку, я учту это и попробую еще раз. - person gdp; 29.04.2011
comment
@Cole W Использование базы игнорирования ‹› подтолкнуло меня к следующей ошибке, которую я смог исправить. Ваше здоровье! - person gdp; 30.04.2011
comment
Бу ... за меня нет награды. Я рад, что смог помочь. - person Cole W; 30.04.2011

Из Автоматическое отображение: базовый тип как стратегия наследования:

Абстрактные базовые классы

Вы заметите, что наш класс Entity абстрактный. Это хорошая практика, но, к сведению, она не является обязательной. Если у вас возникли проблемы, то вряд ли это будет.

В случае, если вам интересно, сделать абстрактный класс - это все равно, что сказать: «Я никогда не буду создавать его напрямую, вместо этого я создам производные классы, такие как Customer и Order (которые наследуются от Entity)».

По умолчанию абстрактные классы рассматриваются как супертипы слоев и фактически не отображаются, вы можете изменить это для определенных сценариев. Самый простой способ сделать это - использовать IncludeBase, где T - ваша сущность.

AutoMap.AssemblyOf<Entity>(cfg)
  .IncludeBase<BaseEntity>();

AutoMap.AssemblyOf<Entity>(cfg)
  .IncludeBase(typeof(BaseEntity<>));

Статья: Автоматическое сопоставление общих базовых классов

person rebelliard    schedule 18.04.2011
comment
Спасибо за ваш вклад. Как мне включить мой базовый класс в качестве BaseEntity типа .IncludeBase ‹BaseEntity‹ ›› (); не работает - person gdp; 18.04.2011
comment
Я изменил свою автокарту, включив в нее базовый объект, но он по-прежнему генерирует только идентификаторы в таблицах. Немного застрял на этом, не знаете, что попробовать? спасибо за вашу помощь до сих пор. - person gdp; 21.04.2011