Migrations EF: annuler la dernière migration appliquée?

436

Cela ressemble à une tâche vraiment courante, mais je ne trouve pas de moyen facile de le faire.

Je souhaite annuler la dernière migration appliquée. Je m'attendais à une commande simple, comme

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

Au lieu de cela, tout ce que je peux trouver, c'est:

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"

(Au moins, je peux utiliser juste le nom, en sautant l'horodatage ...)

Existe-t-il un moyen plus simple?

Cristian Diaconescu
la source
1
Triste, nous voici ici des années plus tard et personne n'a réellement lu la question.
Daniel ZA

Réponses:

162

Depuis EF 5.0, l'approche que vous décrivez est la méthode préférée. Donc

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

ou en utilisant vos exemples de migrations

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Une solution serait de créer un script PS wrapper qui automatise les étapes ci-dessus. De plus, n'hésitez pas à créer une demande de fonctionnalité pour cela, ou mieux encore, essayez de l'implémenter! https://github.com/dotnet/ef6

Andrew Peters
la source
4
Un autre détail: si vous avez une migration manuelle existante, vous devez revenir à, mais vous avez réalisé que votre méthode "Down" ne rétrograde pas vraiment correctement, vous pouvez simplement la modifier et l'enregistrer, puis réexécuter update-database -target .. jusqu'à ce qu'il recule correctement. Modifier la migration manuelle après coup - après l'avoir déjà appliquée - ne la transforme pas en quelque chose qui n'est pas autorisé à être modifié.
Chris Moschini
1
Cela ne fonctionne pas pour moi. Tout ce que je reçois est "la migration cible spécifiée" -1 "n'existe pas.
tutiplain
2
@tutiplain Regardez son deuxième bloc de code. Vous citez ce qu'il souhaite qu'il existe, pas ce qui existe.
Sinjai
quelle est la bonne façon de procéder en utilisant la commande dotnet? Désolé je n'ai pas pu trouver dans la documentation ou il me manque quelque chose. J'ai essayé via entityframeworktutorial.net/efcore/… des suggestions?
Sijan Shrestha
J'ai trouvé la solution, dotnet ef database update LastGoodMigration cependant, cela semble déroutant car je viens d'un arrière-plan de nœud et j'utilise knex, sequlize, ils ont une commande pour annuler la dernière modification, y a-t-il une commande pour annuler la dernière action qui a été appliquée à la base de données ?
Sijan Shrestha
415

Je veux ajouter quelques clarifications à ce fil:

Update-Database -TargetMigration:"name_of_migration"

Ce que vous faites ci-dessus, c'est que vous souhaitez annuler toutes les migrations JUSQU'À ce que vous ayez la migration spécifiée. Ainsi, si vous utilisez GET-MIGRATIONS et que vous trouvez que vous avez A, B, C, D et E, l'utilisation de cette commande annulera E et D pour vous amener à C:

Update-Database -TargetMigration:"C"

De plus, à moins que quelqu'un ne puisse commenter le contraire, j'ai remarqué que vous pouvez utiliser une valeur ordinale et le commutateur -Target court (ainsi, -Target est identique à -TargetMigration). Si vous souhaitez annuler toutes les migrations et recommencer, vous pouvez utiliser:

Update-Database -Target:0

0, ci-dessus, annulerait même la PREMIÈRE migration ( il s'agit d'une commande destructrice - assurez-vous de savoir ce que vous faites avant de l'utiliser! ) - quelque chose que vous ne pouvez pas faire si vous utilisez la syntaxe ci-dessus qui nécessite le nom de la migration cible (le nom de la 0e migration n'existe pas avant qu'une migration ne soit appliquée!). Donc, dans ce cas, vous devez utiliser la valeur 0 (ordinale). De même, si vous avez appliqué les migrations A, B, C, D et E (dans cet ordre), l'ordinal 1 doit faire référence à A, l'ordinal 2 doit faire référence à B, etc. Donc, pour revenir à B, vous pouvez utiliser soit:

Update-Database -TargetMigration:"B"

ou

Update-Database -TargetMigration:2

Modifier octobre 2019:

Selon cette réponse connexe sur une question similaire, la commande correcte est -Targetpour EF Core 1.1 alors qu'elle l'est -Migrationpour EF Core 2.0.

Jazimov
la source
27
Le nom de la migration avec l'index 0 est $InitialDatabase.
MEMark
1
Merci. Existe-t-il des valeurs $ (nom) pour faire référence à d'autres positions d'index, telles que $ LatestDatabase, ou quelque chose comme ça?
Jazimov
Je ne sais pas. Je n'ai pu en trouver par simple googling. Peut-être que parcourir le code source EF les révélerait?
MEMark
3
Pour info, nous sommes juste tombés sur cela et cherchions à faire la même chose que OP ... son utilisation ls variable:*ressemble $InitialDatabasesimplement à une variable PowerShell définie comme 0, il n'y en a pas d'autres définies, même dans le code source EF actuel. Et, get-migrations ne renvoie rien, il écrit seulement sur la console, donc vous ne pouvez pas parcourir les objets retournés ...
DrewJordan
1
Cela devrait être la réponse
WtFudgE
76

Dans EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

20161012160749_AddedOrderToCourseest le nom de la migration vers laquelle vous souhaitez revenir.

MaciejLisCK
la source
3
GEMME! Il m'a fallu un certain temps pour trouver cette réponse (car ils l'ont changé pour .NET Core). Vaut vraiment le coup!
HockeyJ
4
Vous n'avez pas besoin d'inclure la date / l'heure. Vous pouvez simplement mettre le nom.
Richard Marskell - Drackir
1
Cela ne fonctionne pas pour moi ... il dira "Terminé" mais toutes les migrations après celle que je spécifie restent. Et aucun du code "Down" dans aucune de ces migrations n'a été exécuté.
egmfrs
on peut également revenir à une migration spécifique comme celle-ci: Update-Database -Migration: "AddedOrderToCourse" Surtout lorsque vous utilisez des blancs dans les noms de migration, c'est la façon de le faire. (ie Update-Database -Migration "Ordre ajouté au cours")
SwissCoder
13

La solution est:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess
Max
la source
10
Cela est déjà dit dans la question, le demandeur le savait déjà. Je ne vois pas comment cela aide, peut-être pourriez-vous clarifier cela?
ANeves
cette réponse est plus concise. TY Max!
andreikashin
4

Rappel supplémentaire:

Si vous avez plusieurs types de configuration, vous devez spécifier le [ConfigurationName]

Update-Database -Configurationtypename [ConfigurationName] -TargetMigration [MigrationName]
Amos
la source
3

Dans EF Core, vous pouvez entrer la commande Remove-Migrationdans la console du gestionnaire de packages après avoir ajouté votre migration erronée.

La console vous suggère de le faire si votre migration peut entraîner une perte de données:

Une opération a été échafaudée qui peut entraîner la perte de données. Veuillez vérifier la migration pour plus de précision. Pour annuler cette action, utilisez Remove-Migration.

Sean Saúl Astrakhan
la source
3
update-database 0

Avertissement : celaannulera TOUTES les migrations dans EFCore! Veuillez utiliser avec soin :)

mattylantz
la source
2

J'ai constaté que cela fonctionne lorsqu'il est exécuté dans la console du gestionnaire de packages:

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

Vous pouvez créer un script qui le rend plus facile.

Alex Dresko
la source
1

J'utilise EntityFrameworkCore et j'utilise la réponse de @MaciejLisCK. Si vous avez plusieurs contextes de base de données, vous devrez également spécifier le contexte en ajoutant le paramètre de contexte, par exemple:

Update-Database 201207211340509_MyMigration -context myDBcontext

(où se 201207211340509_MyMigrationtrouve la migration vers laquelle vous souhaitez revenir et myDBcontextle nom de votre contexte de base de données)

Chris Halcrow
la source
0

Dans le cas où il y a une possibilité que dataloss EF ne termine pas la commande update-database puisque AutomaticMigrationDataLossAllowed = false par défaut, et roolback l'action à moins que vous ne l' exécutiez avec le paramètre -force .

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

ou

Update-Database TargetMigration:Your_Migration_Index -force
hhk
la source