2016-10-28 16:23:00
When using the code-first approach with Entity Framework 6 System.Decimal
is mapped to SQL data type DECIMAL(18,0)
when creating a database. To fix this we can create a custom attribute and assign it to decimal properties that require a decimal precision other than 0.
Code
[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; } }
Create a class that will apply custom precision to the property configuration.
public class DecimalPrecisionAttributeConvention : PrimitivePropertyAttributeConfigurationConvention_a_m_p_;_lt;DecimalPrecisionAttribute_a_m_p_;_gt; { public override void Apply(ConventionPrimitivePropertyConfiguration configuration, DecimalPrecisionAttribute attribute) {// Guard Clause if (attribute.Precision _a_m_p_;_lt; 1 || attribute.Precision _a_m_p_;_gt;> 38) throw new InvalidOperationException("Precision must be between 1 and 38.");// Guard Clause if (attribute.Scale _a_m_p_;_gt;> attribute.Precision) throw new InvalidOperationException("Scale must be between 0 and the Precision value.");// Do the business configuration.HasPrecision(attribute.Precision, attribute.Scale); } }
Usage
Assign the custom attribute to properties within model classes.
[DecimalPrecision(20,10)] public Nullable_a_m_p_;_lt;decimal_a_m_p_;_gt; Price { get; set; }
Add to DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention()); }