primary framework foreign first enum data code entity-framework ef-code-first sql-types

entity framework - framework - Establecer decimal(16, 3) para una columna en Primer acercamiento de código en EF4.3



enum entity framework (4)

Cómo puedo hacer esto :

private decimal _SnachCount; [Required] [DataType("decimal(16 ,3")] public decimal SnachCount { get { return _SnachCount; } set { _SnachCount = value; } } private decimal _MinimumStock; [Required] [DataType("decimal(16 ,3")] public decimal MinimumStock { get { return _MinimumStock; } set { _MinimumStock = value; } } private decimal _MaximumStock; [Required] [DataType("decimal(16 ,3")] public decimal MaximumStock { get { return _MaximumStock; } set { _MaximumStock = value; } }

Después de generar la base de datos por esta parte de mi modelo, estas tres columnas son decimales (18,2), ¿por qué? ¿Qué es este código de error? Cómo puedo hacer eso ?


El atributo de tipo de DataType es un atributo de validación. Tienes que hacer eso usando el ModelBuilder.

public class MyContext : DbContext { public DbSet<MyClass> MyClass; protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<MyClass>().Property(x => x.SnachCount).HasPrecision(16, 3); modelBuilder.Entity<MyClass>().Property(x => x.MinimumStock).HasPrecision(16, 3); modelBuilder.Entity<MyClass>().Property(x => x.MaximumStock).HasPrecision(16, 3); } }


Esto se copia de la respuesta que publiqué a la misma pregunta aquí; https://.com/a/15386883/1186032 .

Me lo pasé muy bien creando un atributo personalizado para esto:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] public sealed class DecimalPrecisionAttribute : Attribute { public DecimalPrecisionAttribute(byte precision, byte scale) { Precision = precision; Scale = scale; } public byte Precision { get; set; } public byte Scale { get; set; } }

usándolo así

[DecimalPrecision(20,10)] public Nullable<decimal> DeliveryPrice { get; set; }

y la magia ocurre en la creación del modelo con algo de reflexión

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) { foreach (Type classType in from t in Assembly.GetAssembly(typeof(DecimalPrecisionAttribute)).GetTypes() where t.IsClass && t.Namespace == "YOURMODELNAMESPACE" select t) { foreach (var propAttr in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<DecimalPrecisionAttribute>() != null).Select( p => new { prop = p, attr = p.GetCustomAttribute<DecimalPrecisionAttribute>(true) })) { var entityConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(classType).Invoke(modelBuilder, null); ParameterExpression param = ParameterExpression.Parameter(classType, "c"); Expression property = Expression.Property(param, propAttr.prop.Name); LambdaExpression lambdaExpression = Expression.Lambda(property, true, new ParameterExpression[] {param}); DecimalPropertyConfiguration decimalConfig; if (propAttr.prop.PropertyType.IsGenericType && propAttr.prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[7]; decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration; } else { MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[6]; decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration; } decimalConfig.HasPrecision(propAttr.attr.Precision, propAttr.attr.Scale); } } }

la primera parte es obtener todas las clases en el modelo (mi atributo personalizado se define en ese ensamblaje, así que lo usé para obtener el ensamblaje con el modelo)

el segundo foreach obtiene todas las propiedades de esa clase con el atributo personalizado y el atributo en sí mismo para que pueda obtener la precisión y los datos de escala

después de eso tengo que llamar

modelBuilder.Entity<MODEL_CLASS>().Property(c=> c.PROPERTY_NAME).HasPrecision(PRECITION,SCALE);

así que llamo al modelBuilder.Entity () por reflejo y lo almaceno en la variable entityConfig luego construyo la expresión lambda "c => c.PROPERTY_NAME"

Después de eso, si el decimal es nulo, llamo al

Property(Expression<Func<TStructuralType, decimal?>> propertyExpression)

método (lo llamo por la posición en la matriz, no es ideal, lo sé, cualquier ayuda será muy apreciada)

y si no es nulable llamo al

Property(Expression<Func<TStructuralType, decimal>> propertyExpression)

método.

Al tener DecimalPropertyConfiguration, llamo al método HasPrecision.


Puede modificar todas las propinas decimales en la base de datos. En su DBContext en el método OnModelCreating agregar línea:

modelBuilder.Properties<decimal>().Configure(c => c.HasPrecision(18, 3));


También puede establecer la precisión de los decimales usando el enfoque de mapeo de modelos de primer código como este:

public class MyEntityMapping : EntityTypeConfiguration<MyEntity> { public MyEntityMapping() { HasKey(x => x.Id); Property(x => x.Id).IsRequired(); // .HasPrecision(precision, scale) // ''precision'' = total number of digits stored, // regardless of where the decimal point falls // ''scale'' = number of decimal places stored Property(x => x.DecimalItem).IsRequired().HasPrecision(16, 6); } }