efcore2 warns about default values for bool

Created on 28 Jul 2017  路  10Comments  路  Source: dotnet/efcore

I'm in the process of updating a large app from efcore 1.1 to efcore 2preview
Got everything working with the existing models and previous migrations but ran into this problem when adding new properties to the model.

I added a few properties to my model and then wanted to generate a migration. The new props are added like this:

entity.Property(p => p.PwdRequireNonAlpha)
            .IsRequired()
            .HasColumnType("bit")
            .HasDefaultValue(true)
            ;
            entity.Property(p => p.PwdRequireLowercase)
            .IsRequired()
            .HasColumnType("bit")
            .HasDefaultValue(true)
            ;
            entity.Property(p => p.PwdRequireUppercase)
            .IsRequired()
            .HasColumnType("bit")
            .HasDefaultValue(true)
            ;
            entity.Property(p => p.PwdRequireDigit)
            .IsRequired()
            .HasColumnType("bit")
            .HasDefaultValue(true)
            ;

Then when I generated the migration I got a lot of warnings about default values for existing bool properties and also about my new ones like this:

The 'bool' property 'PwdRequireNonAlpha' on entity type 'SiteSettings' is configured with a 
database-generated default. This default will always be used when the property has the value 'false', 
since this is the CLR default for the 'bool' type. Consider using the nullable 'bool?' type instead so that
 the default will only be used when the property value is 'null'.

So that means if later I update the value to false on the entity it will be changed to true?
I don't want a nullable bool, what I want is to add the column and for existing rows make it true.

How can I accomplish that?

closed-fixed type-enhancement

Most helpful comment

@joeaudette For cases where you want to set a default value for use in existing rows when migrating the database, but don't want EF to use the default value for any newly inserted rows you can do this:
C# entity.Property(p => p.PwdRequireNonAlpha) .HasDefaultValue(true) .ValueGeneratedNever();
This tells EF that even though the column has a default, the EF runtime should not make use of that default.

All 10 comments

I am really confused by these warnings about default bool values. Based on the warning it sounds like if my entity has false and the db default is true it would save true when the entity is saved. But testing this with the latest preview it seems to not do that, I can save the entity with a false value even though the database default is true.

So is the warning incorrect? I don't get it

Maybe these warnings only apply on insert? If so that would make more sense to me and not be so scary. If that is true maybe the warning should indicate that because the way it reads now it sounds like it would happen any time the entity is saved, but from testing it works fine when updating.

From testing it does in fact seem that those warnings only apply for inserts of new entities. If the db default of a bool is true but the entity being created has the property as false, it will be true after the entity is created.
But subsequent saves of the entity can save the property as false.

My feedback is that the messages would be less scary if they mentioned the issue affects only inserts.

Closing the issue

We should refine the error message to indicate it is insert time only.

@joeaudette For cases where you want to set a default value for use in existing rows when migrating the database, but don't want EF to use the default value for any newly inserted rows you can do this:
C# entity.Property(p => p.PwdRequireNonAlpha) .HasDefaultValue(true) .ValueGeneratedNever();
This tells EF that even though the column has a default, the EF runtime should not make use of that default.

@ajcvickers thanks for the tip! That is great, does that also eliminate the warning?

What I did to solve it was first add the default as true, generate a migration, then remove the default and generate another migration, and that also worked as the first migration made sure existing rows got true and then the second migration removed the default and eliminated the warnings.

@joeaudette Not sure if it removes the warning, but I will check when I do the work to update the error message.

This warning is confusing. Maybe I want to have a bool not nullable with default value false within SQL Server, defaultvalue ((0)). So when data is added, from app or manually, it automatically sets to false. I do not want a bool? and this warning is not valuable. Am I doing something wrong?

[Warning] The 'bool' property '"Disabled"' on entity type '"SystemUser"' is configured with a database-generated default. This default will always be used when the property has the value 'false', since this is the CLR default for the 'bool' type. Consider using the nullable 'bool?' type instead so that the default will only be used when the property value is 'null'. {EventId: { Id: 200601, Name: "Microsoft.EntityFrameworkCore.Model.Validation.BoolWithDefaultWarning" }, SourceContext: "Microsoft.EntityFrameworkCore.Model.Validation"}

@cgountanis - Have a look at issue https://github.com/aspnet/EntityFrameworkCore/issues/9627 which matches up with your scenario.

@joeaudette it removes the warning.

Was this page helpful?
0 / 5 - 0 ratings