66

I want to set the precision of all the decimal properties to (18,6). In EF6 this was quite easy:

modelBuilder.Properties<decimal>().Configure(x => x.HasPrecision(18, 6));

but I can't seem to find anything similar to this in EF Core. Removing the cascade delete convention wasn't as simple as in EF6 so I found the following workaround:

EF6:

modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

EF Core:

foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
    relationship.DeleteBehavior = DeleteBehavior.Restrict;

and after I read this, I tried a similar approach:

foreach (var entityType in modelBuilder.Model.GetEntityTypes()
    .SelectMany(x => x.GetProperties())
    .Where(x => x.ClrType == typeof(decimal)))
        {
            // what to do here?
        }

I would like if I am on the right track and how to continue, or if not, should I start putting data annotations on all the decimal properties.

Community
  • 1
  • 1
GregoryHouseMD
  • 2,168
  • 1
  • 21
  • 37
  • There is a pretty brute method, but dunno if there are more elegant and flexible ones. You could configure it with `modelBuilder.Entity(c => c.HasColumn("DECIMAL(10,6"))` to specify the type of the column. However, it may couple you to certain types of DB since the types are DB specific – Tseng Apr 07 '17 at 11:57
  • This way I have to list all the decimal properties in the `OnModelCreating` method which is not that different from adding DataAnnotations to all of them, something I'm trying to avoid :) – GregoryHouseMD Apr 07 '17 at 11:59
  • Because I have to move on with development, I set up all 198 decimal properties manually (hopefully I didn't miss any), but if someone thinks of how can I loop trough all of them, please let me know – GregoryHouseMD Apr 07 '17 at 15:25

1 Answers1

169

You got close. Here's the code.

foreach (var property in modelBuilder.Model.GetEntityTypes()
    .SelectMany(t => t.GetProperties())
    .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)))
{
    // EF Core 1 & 2
    property.Relational().ColumnType = "decimal(18, 6)";

    // EF Core 3
    //property.SetColumnType("decimal(18, 6)");

    // EF Core 5
    //property.SetPrecision(18);
    //property.SetScale(6);
}
// EF Core 6
protected override void ConfigureConventions(
    ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Properties<decimal>()
        .HavePrecision(18, 6);
}
bricelam
  • 28,825
  • 9
  • 92
  • 117
  • 42
    Where were you 3h ago when I started typing all 200 properties? :D – GregoryHouseMD Apr 07 '17 at 16:16
  • @GregoryHouseMD If you did some search though, you could have found the duplicate :) – Ivan Stoev Apr 07 '17 at 17:40
  • I did and also commented on one similar Q, but didn't stumble across the duplicate. Are there any performance differences between this answer and the one in the duplicate? – GregoryHouseMD Apr 07 '17 at 17:43
  • 10
    I was banging my head against the wall because I have used this before and it worked, but all of a sudden it wouldn't for a new entity type. Turns out my `decimal` type was actually a nullable `decimal?`. To set the default for both, be sure to match both types using `Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?))` – Sam Sep 22 '18 at 08:13
  • 4
    Is there a way to set the precision in a strongly typed manner? Is there any `HasPrecision` fluent method? – Shimmy Weitzhandler Dec 31 '18 at 07:32
  • 2
    @Shimmy Not yet. Tracked by issue [#11614](https://github.com/aspnet/EntityFrameworkCore/issues/11614). – bricelam Jan 02 '19 at 16:56
  • 2
    This was working nicely but something has gone wrong in EFCore3 - now getting `'IMutableProperty' does not contain a definition for 'Relational' and no accessible extension method 'Relational' accepting a first argument of type 'IMutableProperty' could be found (are you missing a using directive or an assembly reference?)`. Anybody know what I'm missing? – Mikustykus Oct 17 '19 at 07:14
  • 1
    I think it's just `property.SetColumnType()` in 3 – bricelam Oct 17 '19 at 17:54
  • Any changes in net core 6 to just set a defauklt somewhere? – sommmen Jan 25 '22 at 09:25
  • @sommmen I've updated my answer to include code for EF Core 6. – bricelam Jan 26 '22 at 18:08
  • @bricelam thanks mate! this one is still high on the google search results – sommmen Jan 26 '22 at 21:19