Code-first migration: How to set default value for new property?

C#.NetEntity FrameworkEntity Framework-6Entity Framework-Migrations

C# Problem Overview


I am using EF6 for storing instances of the report class in my database. The database already contains data. Say I wanted to add a property to report,

public class report {
    // ... some previous properties

    // ... new property:
    public string newProperty{ get; set; }
}

Now if I go to the package-manager console and execute

add-migration Report-added-newProperty
update-database

I will get a file in the '/Migrations' folder adding a newProperty column to the table. This works fine. However, on the older entries in the database, the value for the newProperty is now an empty string. But I want it to be, e.g., "old".

So my question is: How do I set default values for new properties (of any type) in the migration script (or elsewhere)?

C# Solutions


Solution 1 - C#

If you see the generated migration code you will see AddColumn

AddColumn("dbo.report", "newProperty", c => c.String(nullable: false));

You can add defaultValue

AddColumn("dbo.report", "newProperty", 
           c => c.String(nullable: false, defaultValue: "old"));

Or add defaultValueSql

AddColumn("dbo.report", "newProperty",
           c => c.String(nullable: false, defaultValueSql: "GETDATE()"));

Solution 2 - C#

Hope it helps someone. Putting everything together from previous answers (example using a boolean property):

1) Add a new property to the entity.

/// <summary>
/// Determines if user is enabled or not. Default value is true
/// </summary>
public bool IsEnabled { get; set; }

2) Run the command below to add the new change in the migrations.

add-migration addIsEnabledColumn

3) A migration file is created from the command above, open that file.

enter image description here

4) Set the default value.

public override void Up()
{
        AddColumn(
			"dbo.AspNetUsers", 
			"IsEnabled", 
			c => c.Boolean(
				nullable: false, 
				defaultValue: true
			)
		);
}

Solution 3 - C#

You have to change the line in your migration script which adds the the property/column like this:

AddColumn("dbo.reports", "newProperty", c => c.String(nullable: false, defaultValue: "test"));

Solution 4 - C#

I have resolved this problem by overriding the SaveChanges method. See below for my solution.

  1. Solution Explain

i) Override the SaveChanges method in the DbContext class.

    public override int SaveChanges()
    {
        return base.SaveChanges();
    }

ii) Write logic to set default values

    public override int SaveChanges()
    {
        //set default value for your property
        foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("YOUR_PROPERTY") != null))
        {
            if (entry.State == EntityState.Added)
            {
                if (entry.Property("YOUR_PROPERTY").CurrentValue == null)
                    entry.Property("YOUR_PROPERTY").CurrentValue = YOUR_DEFAULT_VALUE;
            }
        }

        return base.SaveChanges();
    }

2. Example

    public override int SaveChanges()
    {
        //set default value for RegistedDate property
        foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("RegistedDate") != null))
        {
            if (entry.State == EntityState.Added)
            {
                if ((DateTime)entry.Property("RegistedDate").CurrentValue == DateTime.MinValue)
                    entry.Property("RegistedDate").CurrentValue = DateTime.Now;
            }
        }

        //set default value for IsActive property
        foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("IsActive") != null))
        {
            if (entry.State == EntityState.Added)
            {
                if(entry.Property("IsActive").CurrentValue == null)
                    entry.Property("IsActive").CurrentValue = false;
            }
        }

        return base.SaveChanges();
    }

Solution 5 - C#

I found that just using Auto-Property Initializer on entity property is enough to get the job done.

For example:

public class Thing {
    public bool IsBigThing { get; set; } = false;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEluciusFTWView Question on Stackoverflow
Solution 1 - C#Hamid PourjamView Answer on Stackoverflow
Solution 2 - C#Victor LGView Answer on Stackoverflow
Solution 3 - C#nguView Answer on Stackoverflow
Solution 4 - C#shalitha senanayakaView Answer on Stackoverflow
Solution 5 - C#VelyoView Answer on Stackoverflow