4

Assuming I have the following table in my DB:

CREATE TABLE [dbo].[Test]
(
    [Id]      INT            IDENTITY (1, 1) NOT NULL,
    [Active]  BIT            DEFAULT ((1)) NOT NULL,
)

When creating an EF model from this DB, the mapping for the Active bit column, which is mapped to a Boolean column, has no default value (see property "Default Value): Property View - Model Diagram

Why does Entity Framework behave that way? Why doesn't the default value that is defined in the database automatically be applied in the model when the model gets created? The DB states that the default value should be 1, which I assumed would be a default value of true in the model. Do I really have to set the default value for all my columns in the model again?

I checked this behaviour for int and bit columns.


I did some more investigation, and tried to set the "Default Value" property by hand to True and true, and both works.

Manually changed default value

The auto-generated constructor for the Test-entity changes from

public Test()
{
}

to

public Test()
{
    this.Active = true;
}

So default values would be possible in EF, but they are not set when generating the model based on database-first, at least not on my machine.

So, the question still remains: Do I really have to set the default value for all my columns in the model again, even if they are already set in the DB?

5
  • 3
    I have to admit that I mixed up two concepts of "default value" when thinking about this. DB default = If a null value is provided for a given column, use the default value. EF default = If a new instance of a certain entity is created, for each property set the default value (e.g. in the constructor). And these two behaviors are conceputally not the same. Commented Oct 29, 2016 at 16:17
  • 1
    But i would expect EF to take DB-Defaults to your created model as a "default" as well. So the developer just has to change, what has to be changed, but not to have a look at thousands of columns with default values... Otherwise why is a property like "not null" read from db? it could be null in EF, if there is a trigger to handle nulls ot something...??? Commented Oct 31, 2016 at 9:45
  • @swe -> Yes, that's also the the way I expected it to work: Creating an instance of some entity (like Test t = new Test()) would be filled with the default values. So ctx.Tests.Add(t); ctx.SaveChanges(); would result in a new entry in the database, containing an Test-entry with Active = 1, because Active "has not been set set manually" (like you said "only change what has to be changed") and therefore should use the default value. But it seems that's not how EF works... Commented Oct 31, 2016 at 11:53
  • 1
    Not sure why EF does this, but because of problems like this I usually maintain at least two other .sql files along with the one the model generates: ExtraSQL.sql and InitialData.sql. "extra sql" are things like these default values; additional SQL rules that need to be applied that aren't easily done through EF. "initial data" is any data that needs to be in the system for it to function. Then I can execute the three scripts and immediately have a working system. Commented Apr 17, 2017 at 2:17
  • @MarkusWeninger, DB default means when you don't use the column in the insert statement that's when DB put's default value, otherwise it will insert the null value if column allows null or will give error. Commented Sep 30, 2017 at 13:07

3 Answers 3

5

Try this:

StoreGeneratedPattern = Calculated

Edit:

Sorry for the one-code-line answer but I really was in a hurry last day.

To make EF set a property’s db default value, the fastest way is to open your .edmx designer, click on the interested field and set

StoreGeneratedPattern = Calculated

In its properties (you can see this property in your second screenshot, where you set “default value” to true).

Sign up to request clarification or add additional context in comments.

2 Comments

Please add more explanation.
The "StoreGeneratedPattern" value is "Computed", not "Calculated" I assume that is what you actually meant. The problem with that might be that if you would not like to ALWAYS have default value from database, this in my case worked rather poorly. Since if I assign a value within the code while creating an entity, the value will get overwritten by databases default value.
0

This solution solve for all entities that has same property such as CreatedDateTime

public partial class MyEntities : ObjectContext
    {
        public override int SaveChanges(SaveOptions options)
        {
            this.DetectChanges();

            foreach (var insert in this.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added))
            {
                if (insert.Entity.GetType().GetProperty("CreatedDateTime") != null && insert.Entity.GetType().GetProperty("CreatedDateTime").GetType().Name == "DateTime" && (DateTime)(insert.Entity.GetType().GetProperty("CreatedDateTime").GetValue(insert.Entity)) == DateTime.Parse("0001-01-01 00:00:00.0000000"))
                    insert.Entity.GetType().GetProperty("CreatedDateTime").SetValue(insert.Entity, DateTime.UtcNow, null);                
            }
            return base.SaveChanges(options);
        }
    }

referance: https://stackoverflow.com/a/5965743/7731479

Comments

0

My workaround is to create a partial class and define a constructor, which sets the variables that have default values automatically. This doesn't solve your initial problem, but at least you don't have to set the default values after every update.

public partial class Test
{
    public Test()
    {
        this.Active = true;
    }
} 

1 Comment

They don't have to set the value on every update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.