visual tutorial studio .net enums fluent-nhibernate

.net - tutorial - nhibernate visual studio 2017



AsignaciĆ³n de enumeraciĆ³n con nhibernate fluido (3)

Una excelente manera de hacerlo es implementar la interfaz IUserType y Crear un CustomType con las reglas para escribir y leer, que es un ejemplo para boolean:

public class CharToBoolean : IUserType { public SqlType[] SqlTypes => new[] { NHibernateUtil.String.SqlType }; public Type ReturnedType => typeof(bool); public bool IsMutable =>true; public object Assemble(object cached, object owner) { return (cached); } public object DeepCopy(object value) { return (value); } public object Disassemble(object value) { return (value); } public new bool Equals(object x, object y) { if (ReferenceEquals(x, y)) return true; var firstObject = x as string; var secondObject = y as string; if (string.IsNullOrEmpty(firstObject) || string.IsNullOrEmpty(secondObject)) return false; if (firstObject == secondObject) return true; return false; } public int GetHashCode(object x) { return ((x != null) ? x.GetHashCode() : 0); } public object NullSafeGet(IDataReader rs, string[] names, object owner) { var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]); if (obj == null) return null; var value = (string)obj; return value.ToBoolean(); } public void NullSafeSet(IDbCommand cmd, object value, int index) { if(value != null) { if ((bool)value) { ((IDataParameter)cmd.Parameters[index]).Value = "S"; } else { ((IDataParameter)cmd.Parameters[index]).Value = "N"; } } else { ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value; } } public object Replace(object original, object target, object owner) { return original; } }

}

el mapeo:

this.Map(x => x.DominioGenerico).Column("fldominiogen").CustomType<CharToBoolean>();

Es una muestra pero puedes hacer esto con otros tipos.

Estoy siguiendo el http://wiki.fluentnhibernate.org/Getting_started tutorial para crear mi primer proyecto NHibernate con Fluiber NHibernate

Tengo 2 mesas

1) Cuenta con campos

Id AccountHolderName AccountTypeId

2) AccountType con campos

Id AccountTypeName

En este momento, los tipos de cuenta pueden ser Ahorro o Actual, de modo que la tabla Tipos de Cuenta almacena 2 filas 1 - Ahorro 2 - Actual

Para la tabla AccoutType he definido enum

public enum AccountType { Savings=1, Current=2 }

Para la tabla de Cuentas, defino la clase de entidad

public class Account { public virtual int Id {get; private set;} public virtual string AccountHolderName {get; set;} public virtual string AccountType {get; set;} }

Las asignaciones de nhibernate fluidas son:

public AgencyMap() { Id(o => o.Id); Map(o => o.AccountHolderName); Map(o => o.AccountType); }

Cuando intento ejecutar la solución, se produce una excepción: InnerException = {"(XmlDocument) (2,4): error de validación XML: el elemento ''clase'' en el espacio de nombres ''urn: nhibernate-mapping-2.2'' tiene contenido incompleto. Lista de posibles elementos esperados: ''meta, subselect, cache, sincronizar, comentar, tuplizer, id, composite-id'' en el espacio de nombres ''ur ...

Supongo que es porque no he especificado ningún mapeo para AccountType.

Las preguntas son:

  1. ¿Cómo puedo usar AccountType enum en lugar de una clase AccountType?
  2. Tal vez estoy yendo en el camino equivocado. ¿Hay una mejor manera de hacer esto?

¡Gracias!


Aparentemente, lo siguiente ya no funciona https://.com/a/503327/189412

¿Qué tal simplemente haciendo esto?

public AgencyMap() { Id(o => o.Id); Map(o => o.AccountHolderName); Map(o => o.AccountType).CustomType<AccountType>(); }

El tipo personalizado maneja todo :)


public class Account { public virtual int Id {get; private set;} public virtual string AccountHolderName {get; set;} public virtual AccountType AccountType {get; set;} } public AgencyMap() { Id(o => o.Id); Map(o => o.AccountHolderName); Map(o => o.AccountType); }

Fluidez NHibernate guarda los valores enum como cadena por defecto si desea anular que necesita proporcionar una convención para ello. Algo como:

public class EnumConvention : IPropertyConvention, IPropertyConventionAcceptance { #region IPropertyConvention Members public void Apply(IPropertyInstance instance) { instance.CustomType(instance.Property.PropertyType); } #endregion #region IPropertyConventionAcceptance Members 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) ); } #endregion }

Casi olvidé que necesita agregar la convención a su configuración fluida también. Lo haces en el mismo lugar donde agregas las asignaciones:

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<BillingRecordMap>() .Conventions.AddFromAssemblyOf<EnumConvention>()