EF-Migrationen: Rollback der zuletzt angewendeten Migration?

434

Das sieht nach einer wirklich häufigen Aufgabe aus, aber ich kann keinen einfachen Weg finden, dies zu tun.

Ich möchte die zuletzt angewendete Migration rückgängig machen. Ich hätte einen einfachen Befehl erwartet, wie

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

Stattdessen kann ich mir nur Folgendes einfallen lassen:

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"

(Zumindest kann ich nur den Namen verwenden und den Zeitstempel überspringen ...)

Gibt es einen einfacheren Weg?

Cristian Diaconescu
quelle
1
Traurig, hier sind wir Jahre später und niemand hat die Frage wirklich gelesen.
Daniel ZA

Antworten:

160

Ab EF 5.0 ist der von Ihnen beschriebene Ansatz der bevorzugte Weg. Damit

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

oder verwenden Sie Ihre Beispielmigrationen

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Eine Lösung wäre, ein Wrapper-PS-Skript zu erstellen, das die obigen Schritte automatisiert. Sie können auch eine Feature-Anfrage dafür erstellen oder noch besser versuchen, diese zu implementieren! https://github.com/dotnet/ef6

Andrew Peters
quelle
4
Ein weiteres Detail: Wenn Sie über eine vorhandene manuelle Migration verfügen, auf die Sie zurücksetzen müssen, aber festgestellt haben, dass Ihre "Down" -Methode die Dinge nicht richtig zurücksetzt, können Sie sie einfach bearbeiten und speichern und dann update-database -target erneut ausführen. ., bis es richtig zurückrollt. Wenn Sie die manuelle Migration nachträglich ändern, nachdem Sie sie bereits angewendet haben, wird sie nicht zu etwas, das nicht bearbeitet werden darf.
Chris Moschini
1
Das funktioniert bei mir nicht. Alles was ich bekomme ist "spezifizierte
Zielmigration
2
@tutiplain Schau dir seinen zweiten Codeblock an. Sie zitieren, was er wünscht, existiert, nicht was existiert.
Sinjai
Was ist der richtige Weg, dies mit dem Befehl dotnet zu tun? Entschuldigung, ich konnte nicht in der Dokumentation finden oder ich vermisse etwas. Versucht via entityframeworktutorial.net/efcore/… irgendwelche Vorschläge?
Sijan Shrestha
Ich fand die Lösung, dotnet ef database update LastGoodMigrationdies scheint jedoch verwirrend zu sein, da ich von einem Knotenhintergrund komme und knex, sequlize verwende. Sie haben einen Befehl, um die letzte Änderung rückgängig zu machen. Gibt es einen Befehl, um die letzte Aktion zurückzusetzen, die auf die Datenbank angewendet wurde? ?
Sijan Shrestha
415

Ich möchte diesem Thread einige Erläuterungen hinzufügen:

Update-Database -TargetMigration:"name_of_migration"

Was Sie oben tun, ist zu sagen, dass Sie alle Migrationen zurücksetzen möchten, BIS Sie mit der angegebenen Migration belassen haben. Wenn Sie also GET-MIGRATIONS verwenden und feststellen, dass Sie A, B, C, D und E haben, werden mit diesem Befehl E und D zurückgesetzt, um zu C zu gelangen:

Update-Database -TargetMigration:"C"

Außerdem habe ich festgestellt, dass Sie einen Ordnungswert und den kurzen Schalter -Target verwenden können, es sei denn, jemand kann etwas anderes kommentieren (daher ist -Target dasselbe wie -TargetMigration). Wenn Sie alle Migrationen zurücksetzen und neu beginnen möchten, können Sie Folgendes verwenden:

Update-Database -Target:0

0 oben würde sogar die ERSTE Migration rückgängig machen ( dies ist ein destruktiver Befehl - stellen Sie sicher, dass Sie wissen, was Sie tun, bevor Sie ihn verwenden! ) - etwas, das Sie nicht tun können, wenn Sie die obige Syntax verwenden, für die der Name erforderlich ist die Zielmigration (der Name der 0. Migration existiert nicht, bevor eine Migration angewendet wird!). In diesem Fall müssen Sie also den Wert 0 (Ordnungszahl) verwenden. Wenn Sie Migrationen A, B, C, D und E (in dieser Reihenfolge) angewendet haben, sollte sich die Ordnungszahl 1 auf A beziehen, Ordnungszahl 2 auf B usw. Zum Zurücksetzen auf B können Sie entweder Folgendes verwenden:

Update-Database -TargetMigration:"B"

oder

Update-Database -TargetMigration:2

Bearbeiten Oktober 2019:

Gemäß dieser verwandten Antwort auf eine ähnliche Frage gilt der richtige Befehl -Targetfür EF Core 1.1, während er -Migrationfür EF Core 2.0 gilt.

Jazimov
quelle
27
Der Name der Migration mit Index 0 lautet $InitialDatabase.
MEMark
1
Vielen Dank. Gibt es $ (Name) -Werte, die auf andere Indexpositionen verweisen, z. B. $ LatestDatabase oder ähnliches?
Jazimov
Ich weiß es nicht. Ich konnte keine durch einfaches googeln finden. Vielleicht würde das Durchsuchen des EF-Quellcodes sie enthüllen?
MEMark
3
Zu Ihrer Information, wir sind gerade darauf gestoßen und wollten das Gleiche wie OP tun. ls variable:*Es sieht so aus, als wäre $InitialDatabasees einfach eine PowerShell-Variable, die als 0 definiert ist. Es sind keine anderen definiert, selbst im aktuellen EF-Quellcode. Und get-migrations gibt nichts zurück, sondern schreibt nur in die Konsole, sodass Sie nicht über die zurückgegebenen Objekte iterieren können ...
DrewJordan
1
Dies sollte die Antwort sein
WtFudgE
75

In EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

Wo 20161012160749_AddedOrderToCourseist ein Name für die Migration, zu der Sie ein Rollback durchführen möchten?

MaciejLisCK
quelle
2
JUWEL! Ich habe eine Weile gebraucht, um diese Antwort zu finden (da sie für .NET Core geändert wurden). Auf jeden Fall eine Gegenstimme wert!
HockeyJ
4
Sie müssen Datum und Uhrzeit nicht angeben. Sie können einfach den Namen eingeben.
Richard Marskell - Drackir
1
Dies funktioniert bei mir nicht ... es wird "Fertig" angezeigt, aber alle Migrationen nach der von mir angegebenen bleiben bestehen. Und keiner der "Down" -Codes in einer dieser Migrationen wurde ausgeführt.
egmfrs
Man kann auch zu einer bestimmten Migration wie dieser zurückkehren: Update-Database -Migration: "AddedOrderToCourse" Insbesondere wenn Leerzeichen in Migrationsnamen verwendet werden, ist dies der Weg, dies zu tun. (dh Update-Datenbank-Migration "Bestellung zum Kurs hinzugefügt")
SwissCoder
13

Die Lösung ist:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess
Max
quelle
10
Dies ist bereits in der Frage gesagt, der Fragesteller wusste dies bereits. Ich verstehe nicht, wie das hilft, vielleicht könnten Sie das klarer machen?
Aneves
Diese Antwort ist prägnanter. TY Max!
andreikashin
4

Zusätzliche Erinnerung:

Wenn Sie mehrere Konfigurationstypen haben, müssen Sie den [Konfigurationsnamen] angeben.

Update-Database -Configurationtypename [ConfigurationName] -TargetMigration [MigrationName]
Amos
quelle
3

In EF Core können Sie den Befehl Remove-Migrationin der Paketmanagerkonsole eingeben, nachdem Sie Ihre fehlerhafte Migration hinzugefügt haben.

Die Konsole schlägt vor, dies zu tun, wenn bei Ihrer Migration Daten verloren gehen könnten:

Es wurde eine Operation durchgeführt, die zum Verlust von Daten führen kann. Bitte überprüfen Sie die Migration auf Richtigkeit. Verwenden Sie Remove-Migration, um diese Aktion rückgängig zu machen.

Sean Saúl Astrakhan
quelle
3
update-database 0

Warnung : Dadurch werden ALLE Migrationen in EFCore zurückgesetzt! Bitte vorsichtig verwenden :)

mattylantz
quelle
2

Ich habe festgestellt, dass dies funktioniert, wenn es in der Package Manager-Konsole ausgeführt wird:

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

Sie können ein Skript erstellen, das es einfacher macht.

Alex Dresko
quelle
1

Ich verwende EntityFrameworkCore und verwende die Antwort von @MaciejLisCK. Wenn Sie mehrere DB-Kontexte haben, müssen Sie den Kontext auch angeben, indem Sie den Kontextparameter hinzufügen, z.

Update-Database 201207211340509_MyMigration -context myDBcontext

(Wo 201207211340509_MyMigrationist die Migration, auf die Sie zurücksetzen möchten, und myDBcontextder Name Ihres DB-Kontexts)

Chris Halcrow
quelle
0

Falls die Möglichkeit besteht, dass Datenverlust EF den Befehl update-database nicht ausführt, da AutomaticMigrationDataLossAllowed = false standardmäßig ist, und die Aktion zurücksetzt, es sei denn, Sie führen sie mit dem Parameter -force aus .

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

oder

Update-Database TargetMigration:Your_Migration_Index -force
hhk
quelle