Как вы сопоставляете перечисление как значение int с fluent NHibernate?
вопрос говорит, что все это действительно, по умолчанию он отображается как string но мне нужно, чтобы он отображался как int.
В настоящее время я использую PersistenceModel для установки моих конвенций, если это имеет какое-либо значение. Спасибо заранее.
обновление
Обнаружил, что попадание на последнюю версию кода из багажника разрешило мои беды.
7 ответов:
способ определения этого соглашения иногда менялся раньше, теперь:
public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } }
Итак, как уже упоминалось, получение последней версии Fluent NHibernate из багажника привело меня туда, где мне нужно было быть. Пример сопоставления для перечисления с последним кодом:
Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));пользовательский тип заставляет его обрабатываться как экземпляр перечисления, а не использовать
GenericEnumMapper<TEnum>.Я на самом деле рассматриваю возможность отправки патча, чтобы иметь возможность переключаться между перечислимым отображателем, который сохраняет строку, и тем, который сохраняет int, поскольку это похоже на то, что вы должна быть возможность установить в качестве конвенции.
это выскочило на моей недавней деятельности, и все изменилось в новых версиях Fluent NHibernate, чтобы сделать это проще.
чтобы все перечисления отображались как целые числа, теперь вы можете создать соглашение следующим образом:
public class EnumConvention : IUserTypeConvention { public bool Accept(IProperty target) { return target.PropertyType.IsEnum; } public void Apply(IProperty target) { target.CustomTypeIs(target.PropertyType); } public bool Accept(Type type) { return type.IsEnum; } }тогда ваше отображение должно быть только:
Map(quote => quote.Status);вы добавляете соглашение к своему свободному отображению NHibernate вот так;
Fluently.Configure(nHibConfig) .Mappings(mappingConfiguration => { mappingConfiguration.FluentMappings .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>(); }) ./* other configuration */
Не забывайте о перечислениях значение null (например,
ExampleEnum? ExampleProperty)! Их нужно проверять отдельно. Вот как это делается с новой конфигурацией стиля FNH:public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum || (x.Property.PropertyType.IsGenericType && x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) && x.Property.PropertyType.GetGenericArguments()[0].IsEnum) ); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } }
вот как я сопоставил свойство enum со значением int:
Map(x => x.Status).CustomType(typeof(Int32));работает для меня!
для тех, кто использует Fluent NHibernate с Automapping (и потенциально контейнер IoC):
The
IUserTypeConvention- это как @Жюльенответ выше:https://stackoverflow.com/a/1706462/878612public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } }конфигурация Fluent NHibernate Automapping может быть настроена следующим образом:
protected virtual ISessionFactory CreateSessionFactory() { return Fluently.Configure() .Database(SetupDatabase) .Mappings(mappingConfiguration => { mappingConfiguration.AutoMappings .Add(CreateAutomappings); } ).BuildSessionFactory(); } protected virtual IPersistenceConfigurer SetupDatabase() { return MsSqlConfiguration.MsSql2008.UseOuterJoin() .ConnectionString(x => x.FromConnectionStringWithKey("AppDatabase")) // In Web.config .ShowSql(); } protected static AutoPersistenceModel CreateAutomappings() { return AutoMap.AssemblyOf<ClassInAnAssemblyToBeMapped>( new EntityAutomapConfiguration()) .Conventions.Setup(c => { // Other IUserTypeConvention classes here c.Add<EnumConvention>(); }); }*тогда
CreateSessionFactoryсмогите быть использовано в IoC как замок Виндзор (используя PersistenceFacility и установщик) легко. *Kernel.Register( Component.For<ISessionFactory>() .UsingFactoryMethod(() => CreateSessionFactory()), Component.For<ISession>() .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession()) .LifestylePerWebRequest() );
вы можете создать NHibernate
IUserType, и укажите его с помощьюCustomTypeIs<T>()на карте недвижимости.
вы должны сохранить значения как int / tinyint в вашей таблице БД. Для сопоставления вашего перечисления вам нужно правильно указать сопоставление. Пожалуйста, смотрите ниже отображение и перечисление образца,
Сопоставление Класс
public class TransactionMap : ClassMap Transaction { public TransactionMap() { //Other mappings ..... //Mapping for enum Map(x => x.Status, "Status").CustomType(); Table("Transaction"); } }перечисление
public enum TransactionStatus { Waiting = 1, Processed = 2, RolledBack = 3, Blocked = 4, Refunded = 5, AlreadyProcessed = 6, }
Comments