Entity Framework Migrations renaming tables and columns
Nevermind. I was making this way more complicated than it really needed to be.
This was all that I needed. The rename methods just generate a call to the sp_rename system stored procedure and I guess that took care of everything, including the foreign keys with the new column name.
public override void Up()
{
RenameTable("ReportSections", "ReportPages");
RenameTable("ReportSectionGroups", "ReportSections");
RenameColumn("ReportPages", "Group_Id", "Section_Id");
}
public override void Down()
{
RenameColumn("ReportPages", "Section_Id", "Group_Id");
RenameTable("ReportSections", "ReportSectionGroups");
RenameTable("ReportPages", "ReportSections");
}
EF Core Migration recreates renamed tables
As far as I understand, Entity Framework is generally unable to detect when your intention is to just rename a column/table or actually drop it and create something else, so it ends up scaffolding a migration that drops and recreates the column/table.
From the docs:
EF Core is generally unable to know when the intention is to drop a column and create a new one (two separate changes), and when a column should be renamed. If the above migration is applied as-is, all your customer names will be lost. To rename a column, replace the above generated migration with the following:
What you should do in such scenarios is to customize the code of the migration that was automatically scaffolded by EF. In this case, you could take advantage of the methods RenameColumn
and RenameTable
to specify that in the migration only a rename operation should take place.
Hence, after generating the migration, remove the Drop
and Create
statements in both Up
and Down
methods and replace them with the corresponding calls to RenameTable
and RenameColumn
.
For example:
public partial class AddedTrackingProperties : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameTable(
name: "IdentityUserRole", newName: "UserRoles");
// ...
// TODO: other necessary rename tables/columns
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameTable(
name: "UserRoles", newName: "IdentityUserRole");
// ...
// TODO: other necessary rename tables/columns
}
}
How to rename a database column in Entity Framework 5 Code First migrations without losing data?
Manually edit the Up and Down methods of the migration to use the RenameColumn
method to replace the AddColumn
and DropColumn
that it automatically generates for you.
Change or rename a column name without losing data with Entity Framework Core 2.0
EF Core creates its migrations by comparing your models to the current database snapshot (a c# class). It then uses this to create a migration file you can review. However, EF Core cannot always know if you replaced this column or created a new column. When you check your migration file, make sure there are no column drops, index drops (related to this column) etc. You can replace all these with something like this:
migrationBuilder.RenameColumn(
name: "ColumnA",
table: "MyTable",
newName: "ColumnB");
How do I drop a column and create a new one instead of renaming in EF Core?
Sometimes EF can think you want to rename a column, as opposed to creating a column if the types are the same.
It's not an exact science so either create a migration to first delete the column, apply, then create another to add a new one so EF picks up on them as separate operations, or I would just change the migration manually.
In case of the latter option, use the MigrationBuilder.AddColumn
method to add the States
column & then change RenameColumn
to DropColumn
and drop Invites
:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Info",
table: "Articles");
migrationBuilder.DropColumn(
name: "Invites",
table: "Articles");
migrationBuilder.AddColumn(
name: "States",
table: "Articles");
}
In case you ever want to revert the migration, remember to also change the Down(MigrationBuilder migrationBuilder)
method so that it carries out the reverse of your updated Up(...)
method, not the old one:
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn(
name: "Info",
table: "Articles");
migrationBuilder.AddColumn(
name: "Invites",
table: "Articles");
migrationBuilder.DropColumn(
name: "States",
table: "Articles");
}
Related Topics
Asp.Net Core Identity Successful Login Redirecting Back to Login Page
How to Disable Uwp App Suspension
Check for Special Characters (/*-+_@&$#%) in a String
How to Remove Carriage Returns from the Json Output of My Webapi Service
How to Add/Update Child Entities When Updating a Parent Entity in Ef
How to Add Double Quotes to a String That Is Inside a Variable
How to Generate Unique Number of 8 Digits
How to Add a Run Button and Compile Button on the Toolbar in Visual Studio
How to Get the Specific Column in Excel Worksheet Using Documentformat.Openxml C#
.Net Core - How to Properly Kill Started Process
Empty String Not Being Converted to Null When Passing Json Object to Controller
System.Collections.Generic.List Does Not Contain a Definition for 'Select'
How to Remove Empty Lines from a Formatted String
How to Download a File from a Url in C#
How to Get Only Date from a Datetime Value in Razor Page
Fetching Value from a Datatable into Datatable With Where Clause