Entity Framework rollback and remove bad migration
Solution 1:
You have 2 options:
-
You can take the Down from the bad migration and put it in a new migration (you will also need to make the subsequent changes to the model). This is effectively rolling up to a better version.
I use this option on things that have gone to multiple environments.
-
The other option is to actually run
Update-Database –TargetMigration: TheLastGoodMigration
against your deployed database and then delete the migration from your solution. This is kinda the hulk smash alternative and requires this to be performed against any database deployed with the bad version.Note: to rescaffold the migration you can use
Add-Migration [existingname] -Force
. This will however overwrite your existing migration, so be sure to do this only if you have removed the existing migration from the database. This does the same thing as deleting the existing migration file and runningadd-migration
I use this option while developing.
Solution 2:
As the question indicates this applies to a migration in a development type environment that has not yet been released.
This issue can be solved in these steps: restore your database to the last good migration, delete the bad migration from your Entity Framework project, generate a new migration and apply it to the database. Note: Judging from the comments these exact commands may no longer be applicable if you are using EF Core.
Step 1: Restore to a previous migration
If you haven't yet applied your migration you can skip this part. To restore your database schema to a previous point issue the Update-Database command with -TargetMigration option specify the last good migration. If your entity framework code resides in a different project in your solution, you may need to use the '-Project' option or switch the default project in the package manager console.
Update-Database –TargetMigration: <name of last good migration>
To get the name of the last good migration use the 'Get-Migrations' command to retrieve a list of the migration names that have been applied to your database.
PM> Get-Migrations
Retrieving migrations that have been applied to the target database.
201508242303096_Bad_Migration
201508211842590_The_Migration_applied_before_it
201508211440252_And_another
This list shows the most recent applied migrations first. Pick the migration that occurs in the list after the one you want to downgrade to, ie the one applied before the one you want to downgrade. Now issue an Update-Database.
Update-Database –TargetMigration: "<the migration applied before it>"
All migrations applied after the one specified will be down-graded in order starting with the latest migration applied first.
Step 2: Delete your migration from the project
remove-migration name_of_bad_migration
If the remove-migration
command is not available in your version of Entity Framework, delete the files of the unwanted migration your EF project 'Migrations' folder manually. At this point, you are free to create a new migration and apply it to the database.
Step 3: Add your new migration
add-migration my_new_migration
Step 4: Apply your migration to the database
update-database
Solution 3:
For those using EF Core with ASP.NET Core v1.0.0 I had a similar problem and used the following commands to correct it (@DavidSopko's post pointed me in the right direction, but the details are slightly different for EF Core):
Update-Database <Name of last good migration>
Remove-Migration
For example, in my current development the command became
PM> Update-Database CreateInitialDatabase
Done.
PM> Remove-Migration
Done.
PM>
The Remove-Migration will remove the last migration you applied. If you have a more complex scenario with multiple migrations to remove (I only had 2, the initial and the bad one), I suggest you test the steps in a dummy project.
There doesn't currently appear to be a Get-Migrations command in EF Core (v1.0.0) so you must look in your migrations folder and be familiar with what you have done. However, there is a nice help command:
PM> get-help entityframework
Refreshing dastabase in VS2015 SQL Server Object Explorer, all of my data was preserved and the migration that I wanted to revert was gone :)
Initially I tried Remove-Migration by itself and found the error command confusing:
System.InvalidOperationException: The migration '...' has already been applied to the database. Unapply it and try again. If the migration has been applied to other databases, consider reverting its changes using a new migration.
There are already suggestions on improving this wording, but I'd like the error to say something like this:
Run Update-Database (last good migration name) to revert the database schema back to to that state. This command will unapply all migrations that occurred after the migration specified to Update-Database. You may then run Remove-Migration (migration name to remove)
Output from the EF Core help command follows:
PM> get-help entityframework
_/\__
---==/ \\
___ ___ |. \|\
| __|| __| | ) \\\
| _| | _| \_/ | //|\\
|___||_| / \\\/\\
TOPIC
about_EntityFrameworkCore
SHORT DESCRIPTION
Provides information about Entity Framework Core commands.
LONG DESCRIPTION
This topic describes the Entity Framework Core commands. See https://docs.efproject.net for information on Entity Framework Core.
The following Entity Framework cmdlets are included.
Cmdlet Description
-------------------------- ---------------------------------------------------
Add-Migration Adds a new migration.
Remove-Migration Removes the last migration.
Scaffold-DbContext Scaffolds a DbContext and entity type classes for a specified database.
Script-Migration Generates a SQL script from migrations.
Update-Database Updates the database to a specified migration.
Use-DbContext Sets the default DbContext to use.
SEE ALSO
Add-Migration
Remove-Migration
Scaffold-DbContext
Script-Migration
Update-Database
Use-DbContext