¿Cómo mapea una enumeración como un valor int con NHibernate con fluidez?

La pregunta lo dice todo, el valor predeterminado es mapear como una string pero lo necesito para mapear como un int .

Actualmente estoy usando PersistenceModel para configurar mis convenciones si eso hace alguna diferencia. Gracias por adelantado.

Actualización Encontré que acceder a la última versión del código del tronco resolvió mis problemas.

La forma de definir esta convención cambió a veces, ahora es:

 public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } } 

Entonces, como mencioné, sacar la última versión de Fluent NHibernate del maletero me llevó a donde tenía que estar. Un mapeo de ejemplo para una enumeración con el último código es:

 Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus)); 

El tipo personalizado lo fuerza a manejarlo como una instancia de la enumeración en lugar de utilizar GenericEnumMapper .

De hecho, estoy considerando enviar un parche para poder cambiar entre un mapeador enum que persista en una cadena y uno que persista en una int, ya que eso parece algo que debería poder configurar como una convención.


Esto apareció en mi actividad reciente y las cosas han cambiado en las versiones más nuevas de Fluent NHibernate para hacer esto más fácil.

Para hacer que todas las enumeraciones se mapeen como enteros, ahora puede crear una convención como esta:

 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; } } 

Entonces tu mapeo solo tiene que ser:

 Map(quote => quote.Status); 

Usted agrega la convención a su mapeo de Fluiber NHibernate como tal;

 Fluently.Configure(nHibConfig) .Mappings(mappingConfiguration => { mappingConfiguration.FluentMappings .ConventionDiscovery.AddFromAssemblyOf(); }) ./* other configuration */ 

No te olvides de las enumeraciones que ExampleEnum? ExampleProperty valores (como ExampleEnum? ExampleProperty )! Necesitan ser chequeados por separado. Así es como se hace con la nueva configuración de estilo FNH:

 public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria 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); } } 

así es como he mapeado una propiedad enum con un valor int:

 Map(x => x.Status).CustomType(typeof(Int32)); 

¡funciona para mi!

Para aquellos que usan Fluiber NHibernate con Automapping (y potencialmente un contenedor IoC):

IUserTypeConvention es la respuesta de @ Julien anterior: https://stackoverflow.com/a/1706462/878612

 public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } } 

La configuración de Fluent NHibernate Automapping podría configurarse así:

  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( new EntityAutomapConfiguration()) .Conventions.Setup(c => { // Other IUserTypeConvention classes here c.Add(); }); } 

* Entonces CreateSessionFactory se puede utilizar CreateSessionFactory en un IoC como Castle Windsor (utilizando PersistenceFacility e instalador). *

  Kernel.Register( Component.For() .UsingFactoryMethod(() => CreateSessionFactory()), Component.For() .UsingFactoryMethod(k => k.Resolve().OpenSession()) .LifestylePerWebRequest() ); 

Puede crear NHibernate IUserType y especificarlo usando CustomTypeIs() en el mapa de propiedades.

Debes mantener los valores como int / tinyint en tu tabla DB. Para mapear su enumeración, debe especificar la asignación correctamente. Por favor, consulte el mapeo y la muestra enum a continuación,

Clase de mapeo

 clase pública TransactionMap: transacción ClassMap
 {
     public TransactionMap ()
     {
         // Otras asignaciones
         .....
         // Mapeo para enum
         Mapa (x => x.Status, "Estado"). CustomType ();

         Tabla ("Transacción");
     }
 }

Enum

 enum público TransactionStatus
 {
    Esperando = 1,
    Procesado = 2,
    RolledBack = 3,
    Bloqueado = 4,
    Reembolsado = 5,
    AlreadyProcessed = 6,
 } 
    Intereting Posts