J’expérimente avec cette approche code d’abord, mais je suis savoir maintenant qu’une propriété de type System.Decimal obtient le mappage à une colonne sql de type decimal (18, 0).
Comment définir la précision de la colonne de base de données ?
J’expérimente avec cette approche code d’abord, mais je suis savoir maintenant qu’une propriété de type System.Decimal obtient le mappage à une colonne sql de type decimal (18, 0).
Comment définir la précision de la colonne de base de données ?
La réponse de Dave Van den Eynde est maintenant obsolète. Il y a 2 changements importants, à partir de 4.1 EF à partir de la ModelBuilder classe est maintenant DbModelBuilder et il y a maintenant un DecimalPropertyConfiguration.HasPrecision Méthode qui a une signature:
public DecimalPropertyConfiguration HasPrecision(
byte precision,
byte scale )
où la précision est le nombre total de chiffres de la db va stocker, indépendamment de la position du point décimal de chutes et de l'échelle est le nombre de décimales, il va stocker.
Par conséquent, il n'est pas nécessaire pour itérer sur les propriétés comme indiqué mais le peut seulement être appelée à partir de
public class EFDbContext : DbContext
{
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Class>().Property(object => object.property).HasPrecision(12, 10);
base.OnModelCreating(modelBuilder);
}
}
J'ai passé un agréable moment de la création d'un Attribut Personnalisé pour ceci:
[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; }
}
l'utiliser comme ceci
[DecimalPrecision(20,10)]
public Nullable<decimal> DeliveryPrice { get; set; }
et la magie qui se passe à la création du modèle avec un peu de réflexion
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 première partie est d'obtenir toutes les classes dans le modèle (mon attribut personnalisé est défini dans cette assemblée, j'ai donc utilisé que pour obtenir de l'assemblée avec le modèle)
le deuxième foreach obtient toutes les propriétés de la classe avec l'attribut personnalisé, et l'attribut lui-même afin que je puisse obtenir la précision et l'échelle des données
après que j'ai appeler
modelBuilder.Entity<MODEL_CLASS>().Property(c=> c.PROPERTY_NAME).HasPrecision(PRECITION,SCALE);
j'appelle donc le modelBuilder.Entité() par la réflexion et la stocker dans la variable entityConfig puis-je construire le "c => c.PROPERTY_NAME" lambda expression
Après, si la décimale est nullable j'appelle la
Property(Expression<Func<TStructuralType, decimal?>> propertyExpression)
méthode (j'appelle cela par la position dans le tableau, ce n'est pas idéal, je sais, toute aide sera appréciée)
et si ce n'est pas nullable j'appelle la
Property(Expression<Func<TStructuralType, decimal>> propertyExpression)
la méthode.
Avoir la DecimalPropertyConfiguration j'appelle le HasPrecision méthode.
Apparemment, vous pouvez remplacer le DbContext.OnModelCreating() la méthode et configurer la précision comme ceci:
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().Property(product => product.Price).Precision = 10;
modelBuilder.Entity<Product>().Property(product => product.Price).Scale = 2;
}
Mais c'est assez fastidieux de code lorsque vous avez à faire avec tous les prix des propriétés, donc j'ai ceci:
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
var properties = new[]
{
modelBuilder.Entity<Product>().Property(product => product.Price),
modelBuilder.Entity<Order>().Property(order => order.OrderTotal),
modelBuilder.Entity<OrderDetail>().Property(detail => detail.Total),
modelBuilder.Entity<Option>().Property(option => option.Price)
};
properties.ToList().ForEach(property =>
{
property.Precision = 10;
property.Scale = 2;
});
base.OnModelCreating(modelBuilder);
}
C'est une bonne pratique que vous appelez la méthode de base lorsque vous remplacez une méthode, même si la base de la mise en œuvre ne fait rien.
Mise à jour: Cet article a également été très utile.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.