0

This project is using Entity Framework code-first.

I have an entity called Department with a boolean value that specifies whether it is an active department. Here is a simplified version of the entity definition. There are also no fluent mappings for the Active property.

public class Department
{
    public Guid DepartmentId { get; set; }
    public string DepartmentName { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public bool Active { get; set; }
}

In the database the column for Active is a bit, not null.

We have a default constraint in the database for the Active column to set newly created entries to true.

ALTER TABLE [dbo].[Department] ADD  DEFAULT ((1)) FOR [Active]

The problem is that when I create a new entity the user can choose to set Active as false, but this property is false when it is added to the context, but after save changes is called, the property is true and it is true in the database record.

Guid ICommonRepository.AddDepartment(Department newDepartment)
{
    using(var db = new CommonDbContext())
    {
        if(newDepartment.DepartmentId == Guid.Empty)
        {
            newDepartment.DepartmentId = Guid.NewGuid();
        }
        db.Departments.Add(newDepartment); // Here newDepartment.Active is false
        db.SaveChanges();
        return newDepartment.DepartmentId; // Here newDepartment.Active is true
    }
}

Is there a setting in EF or an annotation that I can use on the Active column that will allow me to specify false?

mvanella
  • 3,456
  • 3
  • 19
  • 23
  • 2
    Are you 100% sure there are no annotations or fluent mappings on the property? I was under the impression that sql default values only apply themselves to the model if you have `[DatabaseGenerated(DatabaseGeneratedOption.Identity)]` on the property. – Scott Chamberlain Feb 15 '16 at 19:52
  • 2
    You say "*but this property is false when it is added to the context, but after save changes is called, the property is false and it is false in the database record.*", did you mean to say "*but this property is false when it is added to the context, but after save changes is called, the property is **true** and it is **true** in the database record.*", that is what your code example below is saying is happening. It is not clear to me which problem you are having. Are you ***currently*** getting `newDepartment.Active == true` after you do `db.SaveChanges()` or is that what you wanting to get? – Scott Chamberlain Feb 15 '16 at 19:55
  • `Default constraint` is applied only when column is not provided via `insert` at all. – Ivan Starostin Feb 16 '16 at 06:54
  • @ScottChamberlain That was a typo, it is true in the SQL record and in the entity after save changes. Also I did forget to mention that there is a '[DatabaseGenerated(DatabaseGeneratedOption.Computed)]' annotation on 'Active' but there are no fluent mappings. I've updated the question to reflect those changes. – mvanella Feb 17 '16 at 13:29
  • @IvanStarostin That's what I though, and that's what my experimentation showed me when testing some SQL 'insert' statements. I could insert it as false, but if I didn't provide an 'Active' value it then it was set to true. – mvanella Feb 17 '16 at 13:31
  • 1
    There's your problem. With `DatabaseGeneratedOption.Computed` set, EF will not try to set the value and therefore take the default. Unset this annotation. – Chris Pickford Feb 17 '16 at 13:31
  • @ChrisPickford Thanks, that fixed it. Add it as an answer and I'll mark it as the accepted answer. – mvanella Feb 17 '16 at 13:46

1 Answers1

2

Remove [DatabaseGenerated(DatabaseGeneratedOption.Computed)] from the Active field of your Model.

Entity Framework will not try to persist a value to the database which is why the default is being set.

Chris Pickford
  • 8,642
  • 5
  • 42
  • 73