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?
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