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());
}
Copyright © 2025 delaney. All rights reserved.