orourkedd
orourkedd

Reputation: 6421

Entity Framework 5 Migrations with Data Migration

I have an entity with a string property which I need to externalize to another set of entities:

public class MyEntity
{
    public int Id { get; set; }
    public string FavoriteColor { get; set; }
}

I would like to change this to:

public class MyEntity
{
    public int Id { get; set; }
    public Color FavoriteColor { get; set; }
    public int FavoriteColorId { get; set; }
}

public class Color
{
    public int Id { get; set; }
    public string Name { get; set; }
}

If I create a migration, it creates the new "Color" table in db and then adds the new columns to "MyEntity. How do I ensure that I don't loose all of the data that exists as a string on "MyEntity"? I tried to load the DbContext in the migration to create the new "Color" entityes based on the string data in "MyEntity" but it has problems because it detects that the model is out of sync with the current schema.

Upvotes: 4

Views: 1985

Answers (2)

mehrandvd
mehrandvd

Reputation: 9116

If you create a migration using Add-Migration, a migration file will be scaffold like:

Up()
{
    CreateTable("dbo.Color"...);
    DropColumn("FavoriteColor");
    AddColumn("FavoriteColor", c=>Int(nullable: false));

// Some other code
}

you can alter this file to implement data migration too.

Up()
{
    CreateTable("dbo.Color"...);
    AddColumn("FavoriteColor", c=>Int(nullable: false));

    Sql("INSERT INTO dbo.Color (Id, Name) SELECT DISTINCT FavoriteColor FROM dbo.MyEntity");

    // And the other data corrections here using Sql() method.

    DropColumn("FavoriteColor");

// Some other code
}

Upvotes: 1

glautrou
glautrou

Reputation: 3198

In your project, go to the Package Manager windows and:

  1. Enable migrations: Enable-Migrations
  2. Create migration: Add-Migration Initial
  3. Create upgrade/downgrade script: Update-Database

In you case you are adding a new table (Color) and two new columns.

You have reason, if you start your website the FavoriteColor will be deleted including its data.

What you can do:

In the package manager console when you run Add-Migration Initial that will create a new script (C# file). As you can see in this file there is one column deleted, 2 added and 1 table created.

Make sure the table is created before the columns, populate it with data, create your 2 columns with existing data based on old column and then delete the column.

Another way (perhaps better) is to do this in several migration scripts, you can also use the Seed() method to populate data.

Upvotes: 2

Related Questions