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 ?
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.
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.
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.
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.
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();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With