Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving items to list of items in an Entity Framework migration

I'm using Asp.Net MVC 5 with Entity Framework 6. I've got a table like this:

public class Recipe
{
    [Required]
    public virtual Food Food { get; set; }

    //...rest
}

Now I want to move the Food to a list of foods. Like this:

public class Recipe
{
    public virtual IList<Food> Foods { get; set; }

    //... rest
}

If I try this and add a migration, I'll lose the data related to Food Ids. And won't know which recipe is for which food.

I tried keeping the Food and add the list like this:

public class Recipe
{
    [Required]
    public virtual Food Food { get; set; }

    public virtual IList<Food> Foods { get; set; }

    //... rest
}

But the migration adds a second foreign key and fails to update. Here's the migration code that fails:

    public override void Up()
    {
        DropForeignKey("dbo.Recipes", "Food_ID", "dbo.Foods");
        DropIndex("dbo.Recipes", new[] { "Food_ID" });
        AddColumn("dbo.Foods", "Recipe_Id", c => c.Int());
        AddColumn("dbo.Foods", "Recipe_Id1", c => c.Int());
        AlterColumn("dbo.Recipes", "Food_ID", c => c.Int());
        CreateIndex("dbo.Foods", "Recipe_Id");
        CreateIndex("dbo.Foods", "Recipe_Id1");
        CreateIndex("dbo.Recipes", "Food_ID");
        AddForeignKey("dbo.Foods", "Recipe_Id", "dbo.Recipes", "Id");
        AddForeignKey("dbo.Foods", "Recipe_Id1", "dbo.Recipes", "Id");
        AddForeignKey("dbo.Recipes", "Food_ID", "dbo.Foods", "ID");
    }

How can I move the single Food to a list of Foods without losing the current data in the table?

like image 946
Alireza Noori Avatar asked May 10 '15 11:05

Alireza Noori


People also ask

How do I transfer data in Entity Framework?

If you want to use the framework for changes like this, you should separate Database changes from Data changes. Create a migration for just the Database changes, and execute. Then create a new migration (the Up() and Down() methods will be empty). You can now instantiate your DatabaseContext and there will be no error.

How does migration work in Entity Framework?

The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database.

Which command will roll back to a given migration if already applied to the database?

Reverting a Migration But, for some reason, you want to revert the database to the previous state. In this case, use the update-database <migration name> command to revert the database to the specified previous migration snapshot. > dotnet ef database update MyFirstMigration.


1 Answers

You'll need to customize your migration after creating it.

  1. Modify your entity class

    public class Recipe
    {
        public virtual IList<Food> Foods { get; set; }
    
        //... rest
    }
    
  2. Use Add-Migration to scaffold the migration

  3. Modify the generated migration to fill the new column with data. You'll want to fill the new Recipe_Id column in Foods with the IDs of the previously related rows.

    public override void Up()
    {
        DropForeignKey("dbo.Recipes", "Food_ID", "dbo.Foods");
        DropIndex("dbo.Recipes", new[] { "Food_ID" });
        AddColumn("dbo.Foods", "Recipe_Id", c => c.Int());
    
        // Update values from existing data, not sure if the syntax is perfect
        Sql(@"UPDATE dbo.Foods SET Recipe_Id = r.Id
              FROM (SELECT Id, Food_ID FROM dbo.Recipes) AS r
              WHERE Foods.ID = r.Food_ID");
    
        DropColumn("dbo.Recipes", "Food_ID");
        CreateIndex("dbo.Foods", "Recipe_Id");
        AddForeignKey("dbo.Foods", "Recipe_Id", "dbo.Recipes", "Id");
    }
    
like image 112
jjj Avatar answered Oct 11 '22 06:10

jjj