Хорошо, поэтому вчера мне удалось заставить последние магистральные сборки NHibernate и FluentNHibernate работать с моим последним небольшим проектом. (Я работаю над приложением отслеживания ошибок.) Я создал хороший уровень доступа к данным с помощью шаблона Репозитория.
Я решил, что мои объекты являются ничем специальным, и также что с текущей зрелостью ORMs, я не хочу изготовлять вручную базу данных. Так, я принял решение использовать автоматическую функцию отображения FluentNHibernate с "hbm2ddl.auto" набором свойств NHIBERNATE для "создавания".
Это действительно работает как очарование. Я поместил конфигурацию NHibernate в свой файл конфигурации домена приложения, настроил его и начал играть с ним. (В настоящее время я создал некоторые модульные тесты только.) Это составило все таблицы в базе данных и всем, в чем я нуждаюсь для него. Это даже отобразило мои many-many отношения правильно.
Однако существует несколько маленьких незначительных сбоев:
Существует ли способ сказать автоматический картопостроитель о двух простых правилах выше?
Если ответ будет не, то он будет работать правильно, если я изменю таблицы, он создал? (Так, если я установил некоторые столбцы, чтобы не позволить пустой указатель и изменить позволенную длину для некоторого другого, это будет правильно работать с ними?)
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Большое спасибо всем, кто зашел и выручил. Все мои проблемы с Быстрым решены теперь.
Вы можете использовать переопределения автоматического сопоставления, чтобы изменить способ работы автоматического сопоставления, а также можете определить соглашения, которые вместо этого будут использоваться автоматическим сопоставителем.
Вот пример того, как использовать и соглашения, и переопределения:
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();
}
}
Проверьте эти ссылки, чтобы увидеть больше примеров:
Это мало известно, но вы можете установить многие соглашения в разделе Mappings в вашем коде конфигурации, например
Fluently.Configure()
.Database(/* database config */)
.Mappings(m =>
{
m.FluentMappings
.AddFromAssemblyOf<Entity>()
.Conventions.Add(PrimaryKey.Name.Is(x => "ID"));
})
, чтобы установить соглашение о первичном ключе.
Изменить: Уточнение того, что делает соглашение PrimaryKey:
Соглашение PrimaryKey используется, чтобы указать, какой столбец первичного ключа , а не свойство. Обнаружение свойства - это чистое упражнение по автоматическому отображению, в то время как соглашения применяются к ClassMaps и автоматическим приложениям. - Джеймс Грегори
Это список поддерживаемых соглашений (из вики):
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.
Для ваших проблем с Id, вы необходимо изменить параметр FindIdentity
. Это описано на вики-странице автоматического сопоставления , хотя и вкратце.
Должно получиться примерно следующее:
AutoMap.AssemblyOf<Entity>() // your usual setup
.Setup(s =>
{
s.FindIdentity = m => m.Name == "ID";
});
Это указывает автоматическому преобразователю использовать вашу новую лямбду ( m => m.Name == "ID"
) при попытке обнаружить идентификаторы. m
- свойство / член, и эта лямбда вызывается для каждого свойства в каждой сущности; что бы вы ни вернули, это идентификатор.