Decimal precision and scale in EF Code First

Viewed 218257

I'm experimenting with this code-first approach, but I'm find out now that a property of type System.Decimal gets mapped to a sql column of type decimal(18, 0).

How do I set the precision of the database column?

18 Answers
[Column(TypeName = "decimal(18,2)")]

this will work with EF Core code first migrations as described here.

Edit, From .NET 6, this can been replaced with precision attribute

[Precision(precision, scale)]

Previous version of EF Core:

[Column(TypeName = "decimal(precision, scale)")]

Definitions:

Precision = Total number of characters used

Scale = Total number after the dot. (easy to get confused)

Example:

using System.ComponentModel.DataAnnotations; //.Net Core
using Microsoft.EntityFrameworkCore; //.NET 6+

public class Blog
{
    public int BlogId { get; set; }
    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }
    [Column(TypeName = "decimal(5, 2)")]
    public decimal Rating { get; set; }
    [Precision(28, 8)]
    public decimal RatingV6 { get; set; }
}

More details here: https://docs.microsoft.com/en-us/ef/core/modeling/relational/data-types

From .NET EF Core 6 onwards you can use the Precision attribute.

    [Precision(18, 2)]
    public decimal Price { get; set; }

make sure that you need to install EF Core 6 and do following using line

using Microsoft.EntityFrameworkCore;

Actual for EntityFrameworkCore 3.1.3:

some solution in OnModelCreating:

var fixDecimalDatas = new List<Tuple<Type, Type, string>>();
foreach (var entityType in builder.Model.GetEntityTypes())
{
    foreach (var property in entityType.GetProperties())
    {
        if (Type.GetTypeCode(property.ClrType) == TypeCode.Decimal)
        {
            fixDecimalDatas.Add(new Tuple<Type, Type, string>(entityType.ClrType, property.ClrType, property.GetColumnName()));
        }
    }
}

foreach (var item in fixDecimalDatas)
{
    builder.Entity(item.Item1).Property(item.Item2, item.Item3).HasColumnType("decimal(18,4)");
}

//custom decimal nullable:
builder.Entity<SomePerfectEntity>().Property(x => x.IsBeautiful).HasColumnType("decimal(18,4)");

This is what I was looking for, works for ordinary MVC project (No .Net Core)

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<YOUR_CLASS_NAME>().Property(x => x.YOUR_DECIAML_PROP).HasPrecision(18, 6);

        base.OnModelCreating(modelBuilder);

    }
}

Package manager console

add-migration changeDecimalPrecision

Generated migration

    public override void Up()
    {
        AlterColumn("dbo.YOUR_CLASS_NAME", "YOUR_DECIAML_PROP", c => c.Decimal(nullable: false, precision: 18, scale: 6));
    }
Related