Cristian Diaconescu
Cristian Diaconescu

Reputation: 35611

EF Migrations: Rollback last applied migration?

This looks like a really common task, but I can't find an easy way to do it.

I want to undo the last applied migration. I would have expected a simple command, like

PM> Update-Database -TargetMigration:"-1"

Instead, all I can come up with is:

PM> Get-Migrations

Retrieving migrations that have been applied to the target database.
201208012131302_Add-SystemCategory
201207311827468_CategoryIdIsLong
201207232247409_AutomaticMigration
201207211340509_AutomaticMigration
201207200025294_InitialCreate

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

(At least I can use just the name, skipping the timestamp...)

Is there an easier way?

Upvotes: 587

Views: 582015

Answers (20)

Shad
Shad

Reputation: 453

EF Core Solution

dotnet ef database update Updates the database to the last migration or to a specified migration.

Arguments:

Argument Description
<MIGRATION> The target migration. Migrations may be identified by name or by ID. The number 0 is a special case that means before the first migration and causes all migrations to be reverted. If no migration is specified, the command defaults to the last migration.

If the migration specified is NOT the last migration in the [__EFMigrationsHistory] table, then it will revert all migrations after the specified migration using the specified Down() method on each.

ℹ️ I have found it very worthwhile to always make sure the Down() method will actually undo your migration to bail you out of a bad situation or reduce the pain in switching between branches with different database schemas.

After this, you can revert and re-apply migrations at will (so long as they do not involve 1-way data transformations or loss).

see: https://learn.microsoft.com/en-us/ef/core/cli/dotnet#dotnet-ef-database-update

Note: this process is exactly the same when using VS Package Manager Console, just a different command (Update-Database)

Upvotes: 0

Daniel
Daniel

Reputation: 444

I would add on top of what has been said here already, that if you don't want to let EF do it using the Update-Database command or if you want to have more control over the process, you can simply generate the rollback script, analyse it and then run it yourself.

Having migrations A, B, C, D, running this will generate the rollback script that will bring your database to the state of migration C.

    dotnet ef migrations script D C

Running it backwards (C D) will generate the update script from C to D.

source

Additionally, if you have multiple DbContext classes in your solution, maybe a dedicated Migrations project as well, you will need to specify these details.

dotnet ef migrations script D C -p MigrationsProjectName -s StartupProjectName -c AppDbContextName -o OutputFilePath\rollback.sql

dotnet cli docs

Upvotes: 0

Vitaliy Prushak
Vitaliy Prushak

Reputation: 1162

I have ended up with following solution: When EF creates a migration there are two methods there - Up() and Down() and my solution is based on swapping names for these methods. So, when I need to roll back on that migration I simply rename and Up() method to Down() and vice versa. And it works.

Upvotes: 0

stil
stil

Reputation: 5556

If you work with EF Core on daily basis, you might find efmig tool useful.

After you have configured your database and project details, you just click "Generate rollback script"

efmig main window

after a couple of seconds, it'll generate and show SQL script for you to review and apply: sql script

After applying the rollback script, you can use "Remove from code" action to remove migration code from project. I think it's as simple as it gets.

Disclaimer: I'm the author, the project is open source and I've been using it at my daily work for long time now.

Upvotes: 2

Husam Ebish
Husam Ebish

Reputation: 6758

This solution is effective within a project that is dependent on Entity Framework Core 7.

Remove-Migration -Force

This command will:

  • Reverts the effects of the most recently applied migration on the database without necessitating the use of the "Update-Database" command.
  • Deletes the associated migrations and snapshots.

IMPORTANT

Kindly note that executing this command will not prompt for confirmation. The most recently generated migration and its related database changes will be reversed.

If the migration being rolled back involves the removal of columns or tables, it's important to recognize that there is a possibility of data loss. Any information stored within the columns or tables affected by the removed migration will be lost without any confirmation prompt.

If your application utilizes multiple DbContexts, simply include the name of the targeted DbContext in the command:

Remove-Migration -context <SecondDbContext> -Force

Upvotes: 4

QmlnR2F5
QmlnR2F5

Reputation: 1269

I realised there aren't any good solutions utilizing the CLI dotnet command so here's one:

dotnet ef migrations list
dotnet ef database update NameOfYourMigration

In the place of NameOfYourMigration enter the name of the migration you want to revert to.

Then you can remove all the reverted migrations for good using

dotnet ef migrations remove

Upvotes: 85

Gjaa
Gjaa

Reputation: 1580

EF CORE

Update database to the previous point

update-database CategoryIdIsLong

And then, remove the bad migration

remove-migration

Upvotes: 5

feli_jane
feli_jane

Reputation: 141

EF CORE

PM> Update-Database yourMigrationName

(reverts the migration)

PM> Update-Database

worked for me

in this case the original question (yourMigrationName = CategoryIdIsLong)

Upvotes: 14

LCarter
LCarter

Reputation: 503

I run mine through my (BASH GIT) console also running Entity Framework Core. Update-Database commands will not work outside of the package console and I have to use the donet ef commands.

donet ef database update [Name of previous Migration]

This will run the protected override void Down(MigrationBuilder migrationBuilder) method of your current migration and all of the others to get back to the version of the DB you set it to.

I also use the -p [migration project] -s [Project Solution]. This also allows it to point to my appsettings.[Enviorment].json where my password to access DB is stored.

export ASPNETCORE_ENVIRONMENT=[ENVIORMENT]; donet ef database update [Name of previous Migration] -p [Migration Project Name] -s [Solution Name]

A lot of this might be known but wanted to give detail in case your first time doing.

Upvotes: 7

Andrew Peters
Andrew Peters

Reputation: 11323

As of EF 5.0, the approach you describe is the preferred way. So

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

or using your example migrations

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

One solution would be to create a wrapper PS script that automates the steps above. Additionally, feel free to create a feature request for this, or better yet, take a shot at implementing it! https://github.com/dotnet/ef6

Upvotes: 265

mattylantz
mattylantz

Reputation: 356

update-database 0

Warning: This will roll back ALL migrations in EFCore! Please use with care :)

Upvotes: 9

Alex Dresko
Alex Dresko

Reputation: 5203

I found that this works when run in the Package Manager Console:

dotnet ef migrations list | select -Last 2 | select -First 1 | ForEach-Object { Update-Database -Migration $_ }

You could create a script that makes it easier.

Upvotes: 4

hhk
hhk

Reputation: 548

In case there is a possibility for dataloss EF does not complete the update-database command since AutomaticMigrationDataLossAllowed = false by default, and roolbacks the action unless you run it with the -force parameter.

Update-Database –TargetMigration:"Your migration name" -force

or

Update-Database –TargetMigration:Your_Migration_Index -force

Upvotes: 0

Jazimov
Jazimov

Reputation: 13282

I want to add some clarification to this thread:

Update-Database -TargetMigration:"name_of_migration"

What you are doing above is saying that you want to rollback all migrations UNTIL you're left with the migration specified. Thus, if you use GET-MIGRATIONS and you find that you have A, B, C, D, and E, then using this command will rollback E and D to get you to C:

Update-Database -TargetMigration:"C"

Also, unless anyone can comment to the contrary, I noticed that you can use an ordinal value and the short -Target switch (thus, -Target is the same as -TargetMigration). If you want to rollback all migrations and start over, you can use:

Update-Database -Target:0

0, above, would rollback even the FIRST migration (this is a destructive command--be sure you know what you're doing before you use it!)--something you cannot do if you use the syntax above that requires the name of the target migration (the name of the 0th migration doesn't exist before a migration is applied!). So in that case, you have to use the 0 (ordinal) value. Likewise, if you have applied migrations A, B, C, D, and E (in that order), then the ordinal 1 should refer to A, ordinal 2 should refer to B, and so on. So to rollback to B you could use either:

Update-Database -TargetMigration:"B"

or

Update-Database -TargetMigration:2

Edit October 2019:

According to this related answer on a similar question, correct command is -Target for EF Core 1.1 while it is -Migration for EF Core 2.0.

Upvotes: 513

Mojtaba Nava
Mojtaba Nava

Reputation: 878

Update-Database –TargetMigration:"Your migration name"

For this problem I suggest this link:

https://elegantcode.com/2012/04/12/entity-framework-migrations-tips/

Upvotes: 2

In EF Core you can enter the command Remove-Migration in the package manager console after you've added your erroneous migration.

The console suggests you do so if your migration could involve a loss of data:

An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy. To undo this action, use Remove-Migration.

Upvotes: 5

Chris Halcrow
Chris Halcrow

Reputation: 31940

I'm using EntityFrameworkCore and I use the answer by @MaciejLisCK. If you have multiple DB contexts you will also need to specify the context by adding the context parameter e.g. :

Update-Database 201207211340509_MyMigration -context myDBcontext

(where 201207211340509_MyMigration is the migration you want to roll back to, and myDBcontext is the name of your DB context)

Upvotes: 2

Amos
Amos

Reputation: 2630

Additional reminder:

If you have multiple configuration type, you need to specify the [ConfigurationName]

Update-Database -Configurationtypename [ConfigurationName] -TargetMigration [MigrationName]

Upvotes: 4

MaciejLisCK
MaciejLisCK

Reputation: 3964

In EntityFrameworkCore:

Update-Database 20161012160749_AddedOrderToCourse

where 20161012160749_AddedOrderToCourse is a name of migration you want to rollback to.

Upvotes: 158

Max
Max

Reputation: 538

The solution is:

Update-Database –TargetMigration 201609261919239_yourLastMigrationSucess

Upvotes: 17

Related Questions