Migrazioni EF: ultima migrazione applicata al rollback?


436

Sembra un compito davvero comune, ma non riesco a trovare un modo semplice per farlo.

Voglio annullare l'ultima migrazione applicata. Mi sarei aspettato un comando semplice, come

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

Invece, tutto quello che posso inventare è:

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"

(Almeno posso usare solo il nome, saltando il timestamp ...)

C'è un modo più semplice?


1
Triste, eccoci anni dopo e nessuno ha letto la domanda.
Daniel ZA

Risposte:


162

A partire da EF 5.0, l'approccio che descrivi è il modo preferito. Così

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

o usando le tue migrazioni di esempio

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Una soluzione sarebbe quella di creare uno script PS wrapper che automatizzi i passaggi precedenti. Inoltre, sentiti libero di creare una richiesta di funzionalità per questo, o meglio ancora, prova a implementarla! https://github.com/dotnet/ef6


4
Un altro dettaglio: se si dispone di una migrazione manuale esistente, è necessario eseguire il rollback, ma si è reso conto che il metodo "Giù" in realtà non ripristina correttamente le cose, è possibile modificarlo e salvarlo, quindi rieseguire update-database -target .. fino a quando non torna correttamente. La modifica della migrazione manuale dopo il fatto - dopo averla già applicata - non la trasforma in qualcosa che non può essere modificato.
Chris Moschini,

1
Questo non funziona per me. Tutto quello che ottengo è che "la migrazione target specificata" -1 "non esiste.
tutiplain,

2
@tutiplain Guarda il suo secondo blocco di codice. Stai citando ciò che desidera esistesse, non ciò che esiste.
Sinjai,

qual è il modo corretto di farlo usando il comando dotnet? Spiacente, non sono riuscito a trovare nella documentazione o mi manca qualcosa. Provato tramite entityframeworktutorial.net/efcore/… qualche suggerimento?
Sijan Shrestha,

Ho trovato la soluzione, dotnet ef database update LastGoodMigrationtuttavia, questo sembra confuso poiché provengo da uno sfondo di nodo e usando knex, sequlize, hanno un comando per riverire l'ultima modifica, c'è qualche comando per ripristinare l'ultima azione che è stata applicata al database ?
Sijan Shrestha,

415

Voglio aggiungere alcuni chiarimenti a questa discussione:

Update-Database -TargetMigration:"name_of_migration"

Quello che stai facendo sopra sta dicendo che vuoi eseguire il rollback di tutte le migrazioni FINO A quando rimarrai con la migrazione specificata. Pertanto, se usi GET-MIGRAZIONI e scopri di avere A, B, C, D ed E, allora usando questo comando eseguirai il rollback di E e D per portarti a C:

Update-Database -TargetMigration:"C"

Inoltre, a meno che nessuno possa commentare il contrario, ho notato che è possibile utilizzare un valore ordinale e l'opzione -Target breve (quindi, -Target è uguale a -TargetMigration). Se si desidera ripristinare tutte le migrazioni e ricominciare, è possibile utilizzare:

Update-Database -Target:0

0, sopra, eseguirà il rollback anche della PRIMA migrazione ( questo è un comando distruttivo - assicurati di sapere cosa stai facendo prima di usarlo! ) - qualcosa che non puoi fare se usi la sintassi sopra che richiede il nome di la migrazione di destinazione (il nome della nona migrazione non esiste prima dell'applicazione di una migrazione!). Quindi in quel caso, devi usare il valore 0 (ordinale). Allo stesso modo, se hai applicato le migrazioni A, B, C, D ed E (in quell'ordine), allora l'ordinale 1 dovrebbe fare riferimento ad A, l'ordinale 2 dovrebbe fare riferimento a B e così via. Quindi per eseguire il rollback su B è possibile utilizzare:

Update-Database -TargetMigration:"B"

o

Update-Database -TargetMigration:2

Modifica ottobre 2019:

Secondo questa risposta correlata su una domanda simile, il comando corretto è -Targetper EF Core 1.1 mentre -Migrationper EF Core 2.0.


27
Il nome della migrazione con indice 0 è $InitialDatabase.
MEMark

1
Grazie. Esistono valori $ (nome) per fare riferimento ad altre posizioni dell'indice, come $ LatestDatabase o qualcosa del genere?
Jazimov,

Non lo so. Non sono stato in grado di trovarne nessuno con Google. Forse sfogliare il codice sorgente EF li rivelerebbe?
MEMark

3
Cordiali saluti, ci siamo appena imbattuti in questo e stavamo cercando di fare la stessa cosa di OP ... usarlo ls variable:*sembra $InitialDatabasesemplicemente una variabile di PowerShell definita come 0, non ce ne sono altri definiti, anche nell'attuale codice sorgente EF. E, get-migrations non restituisce nulla, scrive solo sulla console, quindi non puoi iterare sugli oggetti restituiti ...
DrewJordan

1
Questa dovrebbe essere la risposta
WtFudgE,

76

In EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

dove 20161012160749_AddedOrderToCourseè un nome di migrazione che si desidera ripristinare.


3
GEM! Mi ci è voluto un po 'per trovare questa risposta (poiché l'hanno cambiata per .NET Core). Sicuramente merita un voto!
HockeyJ,

4
Non è necessario includere la data / ora. Puoi semplicemente inserire il nome.
Richard Marskell - Drackir il

1
Questo non funziona per me ... dirà "Fatto" ma restano comunque tutte le migrazioni dopo quella che ho specificato. E nessuno del codice "Down" in nessuna di quelle migrazioni è stato eseguito.
egmfrs

si può anche tornare a una migrazione specifica come quella: Update-Database -Migration: "AddedOrderToCourse" Soprattutto quando si usano spazi vuoti nei nomi di migrazione, questo è il modo di farlo. (es. Update-Database -Migration "Ordine aggiunto al corso")
SwissCoder

13

La soluzione è:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess

10
Questo è già stato detto nella domanda, chi l'ha già saputo. Non vedo come questo aiuti, forse potresti renderlo più chiaro?
ANeves

questa risposta è più concisa. TY Max!
andreikashin

4

Promemoria aggiuntivo:

Se si dispone di più tipi di configurazione, è necessario specificare il [Nome configurazione]

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

3

In EF Core puoi inserire il comando Remove-Migrationnella console di gestione dei pacchetti dopo aver aggiunto la migrazione errata.

La console suggerisce di farlo se la migrazione potrebbe comportare una perdita di dati:

È stata impilata un'operazione che può comportare la perdita di dati. Si prega di rivedere la migrazione per la precisione. Per annullare questa azione, utilizzare Remove-Migration.


3
update-database 0

Avviso : questo ripristinerà TUTTE le migrazioni in EFCore! Si prega di utilizzare con cura :)


2

Ho scoperto che funziona quando eseguito nella console di Package Manager:

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

È possibile creare uno script che lo rende più semplice.


1

Sto usando EntityFrameworkCore e utilizzo la risposta di @MaciejLisCK. Se si hanno più contesti DB, sarà necessario specificare anche il contesto aggiungendo il parametro di contesto, ad esempio:

Update-Database 201207211340509_MyMigration -context myDBcontext

(dov'è 201207211340509_MyMigrationla migrazione a cui vuoi tornare indietro ed myDBcontextè il nome del tuo contesto DB)



0

Nel caso in cui sia possibile che dataloss EF non completi il ​​comando update-database poiché AutomaticMigrationDataLossAllowed = false per impostazione predefinita e esegue il roolback dell'azione a meno che non venga eseguita con il parametro -force .

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

o

Update-Database TargetMigration:Your_Migration_Index -force
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.