Автоматическое сопоставление не имеет сопоставленного идентификатора - PullRequest
3 голосов
/ 30 марта 2010
My Entity Class:
public class Building 
    {
        /// <summary>
        /// internal Id 
        /// </summary>
        public virtual long Id { get; set; }
..............
}

Мое сопоставление:

var model = AutoMap.AssemblyOf<Building>()
                        .Setup(s => s.FindIdentity = p => p.Name == "Id")
                        .Where(t => t.Namespace == "SpikeAutoMappings");

var database = Fluently.Configure()
                        .Database(DatabaseConfigurer)
                        .Mappings(m=>m.AutoMappings.Add(model));

Мне нужен кто-то, кто поможет мне понять, что не так, потому что у меня появляется эта ошибка при запуске модульного теста:

Initialization method TestProject1.MappingTestBase.TestInitialize threw exception. FluentNHibernate.Cfg.FluentConfigurationException:  FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

 --->  FluentNHibernate.Visitors.ValidationException: The entity doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id)..

Ответы [ 3 ]

9 голосов
/ 21 февраля 2011

оба ответа верны; если вы не укажете по-другому, автоматическое устройство предполагает, что у вас есть поле int Id.
Если ваш Id длинный, автопроизводитель может не распознать его правильно.
попробуйте определить MappingOverride для вашего класса (классов), например:

public class UserMappingOverride : IAutoMappingOverride<User>
{
    #region IAutoMappingOverride<User> Members

    public void Override(AutoMapping<User> mapping)
    {
        mapping.Id(u => u.Name);
    }

    #endregion
}

функция Id () позволяет вам переопределить соглашение о том, каким должно быть поле идентификатора.
Подробнее о переопределении см. http://wiki.fluentnhibernate.org/Auto_mapping#Overrides.
Cheers,
Jhonny

1 голос
/ 01 февраля 2011

Как правило, использование AutoMapping является плохой политикой, поскольку поле Id должно существовать в таблицах вашей базы данных. Вместо этого рассмотрите возможность использования генератора отображений, например NMG , для обработки сопоставления.

В этом случае вы сначала захотите загрузить / установить приложение, а затем сгенерировать файлы сопоставления из своей базы данных (Oracle, SQL и другие).

Чтобы создать файлы сопоставления, сначала создайте папку /Entities/ в своем проекте. Затем настройте программное обеспечение генератора следующим образом:

Preferences

  1. Имя сгенерированного свойства = совпадает с именем столбца базы данных (без изменений)
  2. Стиль отображения = Свободное отображение
  3. Поле или свойство = Авто свойство

Доступные языки: C # и VB

  1. Папка: [your project folder]\Entities
  2. Пространство имен: [your project namespace].Entities
  3. Название сборки: [your project name].Entities

Далее, либо «Создать все», либо «Создать конкретную таблицу».

Все файлы *.cs и *Map.cs теперь должны быть созданы в вашем проекте (вы можете добавить их с помощью Add Existing Item..., если они не отображаются).

Используя Fluent, вы увидите что-то вроде следующего:

Id(x => x.keyName_ID)
  .Column(x => x.keyname_ID)
  .GeneratedBy
  .Sequence("keyname_ID")

или

Id(x => x.keyName_ID)
  .Column(x => x.keyname_ID)
  .GeneratedBy
  .Identity()
  .Column("keyname_ID")

или

Id(x => x.keyName_ID)
  .Column(x => x.keyname_ID)
  .GeneratedBy
  .Assigned()

Итак, теперь нам нужно указать Id, используя FluentMapping с Fluent nHibernate. Для этого вам нужно переписать строку Id кода в каждом из файлов Map в решении. Просто добавьте:

Id(x => x.KeyName_ID)
  .GeneratedBy
  .GetGeneratorMapping()
  .IsSpecified("KeyName_ID");

Где keyname_id - это имя столбца id в вашей базе данных, а не созданный.

Обратите внимание, что в вашем отображении на BuildSession вы должны иметь:

(...).Mappings(m => 
    m.FluentMappings.AddFromAssemblyOf<[one of your entities]>()
);

И теперь Id сопоставлено. :) Надеюсь, это поможет!

0 голосов
/ 31 марта 2010

Мой опыт работы с Automapping заключается в том, что до тех пор, пока у вашего класса Entity есть строка:

    public virtual int Id { get; private set; }

автоматический обработчик будет обрабатывать его как идентификатор без дополнительной помощи со стороны программиста (т.е. нет необходимости в коде FindIdenity, который вы используете при вызове AutoMap).

Единственное отличие, которое я вижу в вашем объявлении ID, состоит в том, что вы используете тип long вместо int. Не знаю, имеет ли это значение или нет.

...