Как точно настроить автоматический картограф FluentNHibernate? - PullRequest
5 голосов
/ 26 апреля 2010

Хорошо, поэтому вчера мне удалось получить последние сборки стволов NHibernate и FluentNHibernate для работы с моим последним небольшим проектом. (Я работаю над приложением отслеживания ошибок.) Я создал хороший слой доступа к данным, используя шаблон Repository.

Я решил, что мои сущности не являются чем-то особенным, а также, что с текущей зрелостью ORM я не хочу вручную создавать базу данных. Поэтому я решил использовать функцию автоматического сопоставления FluentNHibernate со свойством NHibernate "hbm2ddl.auto", установленным на "create".

Это действительно работает как шарм. Я поместил конфигурацию NHibernate в файл конфигурации домена моего приложения, настроил его и начал играть с ним. (В настоящее время я создал только несколько модульных тестов.) Он создал все таблицы в базе данных и все, что мне для этого нужно. Это даже правильно сопоставило мои отношения «многие ко многим».

Однако есть несколько небольших глюков:

  • Все столбцы, созданные в БД, допускают нулевое значение. Я понимаю, что он не может предсказать, какие свойства должны разрешать null, а какие нет, но, по крайней мере, я хотел бы сказать, что он должен разрешать null только для тех типов, для которых null имеет смысл в .NET (например, non типы значений со значением NULL не должны иметь значение null).
  • Все созданные им столбцы nvarchar и varbinary имеют длину по умолчанию 255. Я бы предпочел, чтобы они были на максимуме вместо этого.

Есть ли способ рассказать авто картографу о двух простых правилах выше?

Если ответ «нет», будет ли он работать правильно, если я изменю созданные им таблицы? (Итак, если я установлю некоторые столбцы, чтобы они не допускали пустое значение, и изменил разрешенную длину для другого, будет ли он корректно работать с ними?)

ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Большое спасибо всем, кто зашел и помог. Все мои проблемы с Fluent решены.

Ответы [ 3 ]

6 голосов
/ 26 апреля 2010

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

Вот пример того, как использовать оба соглашения и переопределения:

var mappings = new AutoPersistenceModel();
mappings.Conventions.Setup(s => s.Add<ColumnNullabilityConvention>());
mappings.UseOverridesFromAssemblyOf<AssemblyName>();

// This convention will set all properties to be not nullable

public class ColumnNullabilityConvention: IPropertyConvention, IPropertyConventionAcceptance
{
   public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
   {
       criteria.Expect(x => x.Nullable, Is.Not.Set);
   }

   public void Apply(IPropertyInstance instance)
   {
       instance.Not.Nullable();
   }
}

// This override will change "string" to use "text" instead of "varchar(255)".
// Also set the property to be not nullable

public class SomeOverrideInTheSameAssembly : IAutoMappingOverride<TypeName>
{
   public void Override(AutoMapping<TypeName> mapping)
   {
       mapping.Map(x => x.Property).CustomType("StringClob").CustomSqlType("text");
       mapping.Map(x => x.Property).Not.Nullable();
   }
}    

Проверьте эти ссылки для большего количества примеров:

3 голосов
/ 28 апреля 2010

Для проблем с Id вам необходимо изменить настройку FindIdentity. Это описано на вики-странице , хотя и кратко.

Это должно выглядеть примерно так:

AutoMap.AssemblyOf<Entity>() // your usual setup
  .Setup(s =>
  {
    s.FindIdentity = m => m.Name == "ID";
  });

То, что это делает, инструктирует автопроизводителя использовать вашу новую лямбду (m => m.Name == "ID") при попытке обнаружить идентификаторы. m - это свойство / член, и эта лямбда вызывается для каждого свойства в каждой сущности; что бы вы ни вернули, истина - это идентификатор.

1 голос
/ 26 апреля 2010

Это не так широко известно, но вы можете установить множество соглашений из раздела Mappings в вашем коде настройки, например,

Fluently.Configure()
  .Database(/* database config */)
  .Mappings(m =>
  {
    m.FluentMappings
      .AddFromAssemblyOf<Entity>()
      .Conventions.Add(PrimaryKey.Name.Is(x => "ID"));
  })

для установки соглашения первичного ключа.

Редактировать: Разъяснение того, что делает соглашение PrimaryKey:

Соглашение PrimaryKey используется для укажите, что столбец из Первичный ключ есть, а не собственность. Открытие собственности является чистым автоматическое упражнение, в то время как соглашения применяются к ClassMaps и autoppings. - Джеймс Грегори

Это список поддерживаемых соглашений (из вики):

Table.Is(x => x.EntityType.Name + "Table")
PrimaryKey.Name.Is(x => "ID")
AutoImport.Never()
DefaultAccess.Field()
DefaultCascade.All()
DefaultLazy.Always()
DynamicInsert.AlwaysTrue()
DynamicUpdate.AlwaysTrue()
OptimisticLock.Is(x => x.Dirty())
Cache.Is(x => x.AsReadOnly())
ForeignKey.EndsWith("ID")

См. Раздел простейших условных обозначений на вики FNH.

...