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 Food
s without losing the current data in the table?
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.
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.
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.
You'll need to customize your migration after creating it.
Modify your entity class
public class Recipe { public virtual IList<Food> Foods { get; set; } //... rest }
Use Add-Migration
to scaffold the migration
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");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With