I'm renaming several tables and columns. Since I don't want to lose the existing data, I created a migration from scratch.
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameTable(name: "Providers", schema: "dbo", newName: "Vendors", newSchema: "dbo");
migrationBuilder.RenameTable(name: "ProviderContacts", schema: "dbo", newName: "VendorContacts", newSchema: "dbo");
migrationBuilder.RenameColumn(name: "ProviderId", table: "AspNetUsers", newName: "VendorId", schema: "dbo");
migrationBuilder.RenameColumn(name: "ProviderId", table: "VendorContacts", newName: "VendorId", schema: "dbo");
migrationBuilder.RenameColumn(name: "ProviderId", table: "Locations", newName: "VendorId", schema: "dbo");
}
I then ran Update-Database
. But this still leaves a bunch of indexes and foreign keys that should also be renamed. So I used the Add-Migration
command to bring any remaining changes up to date.
But I notice the new migration seems to be dropping and recreating tables and columns that my custom migration already renamed.
migrationBuilder.DropTable(
name: "ProviderContacts");
migrationBuilder.DropTable(
name: "Providers");
migrationBuilder.DropIndex(
name: "IX_Locations_ProviderId",
table: "Locations");
migrationBuilder.DropIndex(
name: "IX_AspNetUsers_ProviderId",
table: "AspNetUsers");
migrationBuilder.DropColumn(
name: "ProviderId",
table: "Locations");
migrationBuilder.DropColumn(
name: "ProviderId",
table: "AspNetUsers");
My question is: What is the Add-Migration
command comparing? Is it looking at the database or something else? Why didn't it recognize that these tables and columns have been renamed?
How can I get it to recognize the changes in my custom migration?
In EF Core, Update-Database
uses the IMigrationsAssembly
service to discover migrations compiled into your assembly. It fetches the list of migrations that have been run against this database using another service. As the migrations are executed the list of migrations are updated in a table. The process doesn't know or care about the state of your database model, it doesn't cause any change in your database model. The process is designed to work against other databases, without any knowledge of your development environment.
Running Add-Migration
uses the IMigrationsAssembly
service to load the previous ModelSnapshot
that has been compiled into your assembly, and the model from your contexts OnModelCreating
method. Then it uses the IMigrationsModelDiffer
service twice to compare the two models and produce the Up and Down migration routines. The new migration and ModelSnapshot
is then serialised back into source code and written to disk. This process knows nothing about the state of any database, or the list of operations in previous migrations.
In other words, Add-Migration
doesn't care that you've written another migration. It's still going to compare these two models. The migration differ isn't perfect, if the before and after tables are too different it will generate drop & create steps.
Another option is to perform one change at a time, creating new migrations for each step. Then merge the Up & Down methods into the last migration. And delete the rest.