36

I have an existing table / model into which I want to drop a new Boolean column. This table already has many hundreds of rows of data, and I can't touch the existing data. But.. This column will NOT be nullable, so I need to provide a default value of true to all the rows that currently exist.

public class Revision
{
    ...
    public Boolean IsReleased { get; set; }
    ....
}

IMPORTANT:

(This was in the OP, but people seemed to miss is.)

When databases are updated with the migration, all existing rows which receive this new column MUST have their values set to True.

Casey Crookston
  • 13,016
  • 24
  • 107
  • 193

5 Answers5

44

You can avoid using fields and take advantage of Auto-property initialization, a feature new in C# 6.

This will set the default value to true when the column is added to your database.

public class Revision
{
    ...
    public Boolean IsReleased { get; set; } = true;
    ....
}

Edit to include @BrewMate's comment:

If all of your values set to false when you update the database, make sure to have the JSON formatter handle default values. The JSON formatter will ignore default values by default and then your database is setting the boolean to its default value, false. See the link below, I would try Default as the enumeration: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DefaultValueHandling.htm

Saamer
  • 4,687
  • 1
  • 13
  • 55
Brandon Minnick
  • 13,342
  • 15
  • 65
  • 123
  • 1
    ah ok! Will this set existing rows in existing DB's to true when the column is added? – Casey Crookston Dec 02 '16 at 16:57
  • 1
    Yes. I've used this same technique when adding new columns to my database. – Brandon Minnick Dec 02 '16 at 16:58
  • I had to rescind this as the answer. It set all the values to False when I did a database-update – Casey Crookston Dec 02 '16 at 17:19
  • @Casey Crookston You did well to update your question because judging from other answers a lot of people here, including me, got confused about what actually are you trying to achieve. – Alex Dec 02 '16 at 18:13
  • 1
    @CaseyCrookston The reason all your values set to false when you updated the database is because you need to have the json formatter handle default values. The json formatter will ignore default values by default and then your database is setting the boolean to it's default value, false. See the link below, I would try Default as the enumeration. http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DefaultValueHandling.htm – BrewMate Dec 02 '16 at 18:41
  • @Alex... it was right there in plain English, but, I took your advice. – Casey Crookston Dec 02 '16 at 18:50
  • I test Auto-property initialization but it not worked for me. – Aref Hemati Dec 08 '19 at 08:41
42

Another option is create a default constructor and set the properties with the default values you need:

public class Revision
{
    public Boolean IsReleased { get; set; }

    public Revision()
    {
        IsReleased=true;

    }
}

To set the values to true of the existing rows when you run Update-Database command, you could do this in your Configuration class:

protected override void Seed(YourContext context)
{
    var entities=context.Revisions.Where(r=>!r.IsReleased)
    foreach(var e in entities)
    {
      e.IsReleased=true;
     //context.Entry(e).State = EntityState.Modified; If you have disabled change tracking then add this line
    }
    context.SaveChanges();
}

Update

If it is a new column you are adding via migration maybe you can also do this:

AddColumn("dbo.Revisions", "IsReleased", c => c.Boolean(nullable: false, defaultValue: true));
ocuenca
  • 38,548
  • 11
  • 89
  • 102
16

According to the MSDN, DefaultValueAttribute specifies the default value for a property. You can use DefaultValueAttribute as the following:

public class Revision
{
    ...
    [DefaultValue(true)]
    public Boolean IsReleased { get; set; } = true;
    ....
}

Furthermore you can use UP() method inside of DbMigration class as the following:

public partial class InitializeDb : DbMigration
{
    public override void Up()
    {
            CreateTable(
            "dbo.Revision",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    ...
                    IsReleased = c.Boolean(nullable: false, defaultValue: true),
                    ...
                })
            .PrimaryKey(t => t.Id);
    }
}

You should add "defaultValue: true" by yourself.

Varan Sinayee
  • 1,105
  • 2
  • 12
  • 26
0

Unfortunately I wasn't on the version of C# to be able to use @Brandon Minnick's suggestion which seems the simplest. Other suggestions just seemed like to much work instead I ended up doing this: https://stackoverflow.com/a/46436861/1819403

Anthony Griggs
  • 1,469
  • 2
  • 17
  • 39
-1

You can simply avoid auto-implemented properties and set the property value to true when you initialize your object.

private Boolean _isReleased = true;
public Boolean IsReleased 
{ 
    get
    {
        return _isReleased;
    }
    set
    {
        _isReleased = value;
    }
}
Brandon Minnick
  • 13,342
  • 15
  • 65
  • 123
Alex
  • 1,433
  • 9
  • 18
  • ok, I was hoping it would be this simple. Will this set existing rows in existing DB's to true when the column is added? – Casey Crookston Dec 02 '16 at 16:21
  • No. To do that you simply make sure you set default value of your column to `TRUE` when you create it. https://msdn.microsoft.com/en-us/library/ms187872.aspx – Alex Dec 02 '16 at 16:34
  • 2
    Ok, but the idea here is that we are doing this via Entity Framework code-first migrations. That's the whole point. – Casey Crookston Dec 02 '16 at 16:55