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