Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set another value on a boolean with defaut value with Entity Framework Core?

I got quite the same problem in this question : How to override SQL Server default value constraint on a boolean when inserting new entity? [closed]

Like him, I get the good value of my boolean from the client to the controller, false, but it's set to true by the call of _context.SaveChanges(); because of Entity Framework and the default value constraint in the database.

BUT : I'm using Entity Framework Core and I don't have any [DatabaseGenerated(DatabaseGeneratedOption.Computed)] annotation to remove to fix the problem.

In my ApplicationDbContext.cs :

modelBuilder.Entity<myEntity>(entity =>
{
    entity.Property(e => e.Active).HasDefaultValueSql("1");
    //entity.Property(e => e.Active).HasDefaultValueSql<bool>("1"); // doesn't fix
    ...
}

In my Database :

CREATE TABLE myEntity(
    Id      INTEGER IDENTITY(1,1) NOT NULL,
    ...
    Active  BIT NOT NULL CONSTRAINT DF_myEntity_Active DEFAULT 1
);

In my Controller :

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id, Active, etc.")] Entity myEntity)
{
    if (ModelState.IsValid)
    {
        _context.Add(myEntity); // here myEntity.Active = false
        await _context.SaveChangesAsync();
        // same problem with _context.SaveChanges(); in another controller
        // here myEntity.Active = true
    }
    ...
}

It seems that EF doesn't map C# boolean with SQL bit correctly and always takes the default value. Does somebody have an issue to force the false value ?

like image 890
Korgoth Avatar asked Jul 25 '16 14:07

Korgoth


People also ask

How do I change the default Boolean value?

Use the create() or update() methods to specify the value of the new property as its default value, that is, false for boolean or 0 for integer. The property value should get updated successfully.

How do I set the default value in Entity Framework?

In the DbContext OnModelCreating you add the default value. The 'bool' property 'Active' on entity type 'Foundation' is configured with a database-generated default. This default will always be used for inserts when the property has the value 'false', since this is the CLR default for the 'bool' type.

What is ValueGeneratedOnAdd?

The Entity Framework Core Fluent API ValueGeneratedOnAdd method indicates that the value for the selected property is generated by the database whenever a new entity is added to the database. Therefore, the property should be ignored by EF Core when constructing an INSERT statement.

How can we specify computed generated column in Entity Framework?

The Entity Framework Core Fluent API HasComputedColumnSql method is used to specify that the property should map to a computed column. The method takes a string indicating the expression used to generate the default value for a database column.


2 Answers

I don't think you can set default values with annotations. However, I have found a rather tricky workaround after researching this issue myself.

If you set your bool value to be nullable, then use the fluent api to set the default, you should be fine. Its not perfect, but it works:

public class Year
{
        public int Id { get; set; }
        public string label { get; set; }
        public int year { get; set; }
        public bool? active { get; set; }
}

Then, in your data context, set the default value:

            modelBuilder.Entity<Year>()
            .Property("active")
            .HasDefaultValue(true);

When you insert new records into the database, you won't need to specify the boolean property in your object declaration. Below, the year 2017 will have a default value of true.

            var newYears = new List<Year>();

            newYears.Add(new Year { label = "2019", year = 2019, active = false });
            newYears.Add(new Year { label = "2018", year = 2018, active = true });
            newYears.Add(new Year { label = "2017", year = 2017});
            _context.Years.AddRange(newYears);
            _context.SaveChanges();
like image 97
Rick B Avatar answered Nov 14 '22 22:11

Rick B


I have also faced almost similar issue with nullable bool value. I was using EF on top of Sqlite db. For me the update value true/false was not reflecting in the db. After I have overridden the OnModelCreating method and configured the property as below

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyEntity>()
        .Property(p => p.IsActive).ValueGeneratedNever().HasDefaultValue(null);
    }

After this changes as the values were updated as per expected. Hope this may help you as well.

like image 34
Kiran Paul Avatar answered Nov 14 '22 22:11

Kiran Paul