EF Migraciones: ¿Deshacer la última migración aplicada?

436

Esto parece una tarea realmente común, pero no puedo encontrar una manera fácil de hacerlo.

Quiero deshacer la última migración aplicada. Hubiera esperado un comando simple, como

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

En cambio, todo lo que se me ocurre es:

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"

(Al menos puedo usar solo el nombre, omitiendo la marca de tiempo ...)

hay una manera mas facil?

Cristian Diaconescu
fuente
1
Triste, aquí estamos años después y nadie realmente leyó la pregunta.
Daniel ZA

Respuestas:

162

A partir de EF 5.0, el enfoque que describe es la forma preferida. Entonces

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

o usando tus migraciones de ejemplo

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Una solución sería crear un script PS envoltorio que automatice los pasos anteriores. Además, siéntase libre de crear una solicitud de función para esto, o mejor aún, ¡intente implementarlo! https://github.com/dotnet/ef6

Andrew Peters
fuente
44
Otro detalle: si tiene una migración manual existente a la que debe retroceder, pero se dio cuenta de que su método "Down" no revierte las cosas correctamente, puede editarlo y guardarlo, luego volver a ejecutar update-database -target ... . hasta que retroceda correctamente. La modificación de la migración manual después del hecho, después de que ya la haya aplicado, no la convierte en algo que no se puede editar.
Chris Moschini
1
Esto no funciona para mi. Todo lo que obtengo es que "la migración de destino especificada" -1 "no existe.
tutiplain
2
@tutiplain Mira su segundo bloque de código. Citas lo que desea que existiera, no lo que existe.
Sinjai
¿Cuál es la forma correcta de hacer esto usando el comando dotnet? Lo siento, no pude encontrar en la documentación o me falta algo. Intentado a través de entityframeworktutorial.net/efcore/… ¿ Alguna sugerencia?
Sijan Shrestha
Encontré la solución, dotnet ef database update LastGoodMigrationsin embargo, esto parece confuso ya que vengo de un fondo de nodo y uso knex, sequlize, tienen un comando para revertir el último cambio, ¿hay algún comando para revertir la última acción que se aplicó a la base de datos? ?
Sijan Shrestha
415

Quiero agregar algunas aclaraciones a este hilo:

Update-Database -TargetMigration:"name_of_migration"

Lo que está haciendo arriba es decir que desea revertir todas las migraciones HASTA que quede con la migración especificada. Por lo tanto, si usa GET-MIGRATIONS y descubre que tiene A, B, C, D y E, entonces, al usar este comando, E y D retrocederán para llegar a C:

Update-Database -TargetMigration:"C"

Además, a menos que alguien pueda comentar lo contrario, noté que puede usar un valor ordinal y el interruptor corto -Target (por lo tanto, -Target es lo mismo que -TargetMigration). Si desea revertir todas las migraciones y comenzar de nuevo, puede usar:

Update-Database -Target:0

0, arriba, revertiría incluso la PRIMERA migración ( este es un comando destructivo; ¡asegúrese de saber lo que está haciendo antes de usarlo! ), Algo que no puede hacer si usa la sintaxis anterior que requiere el nombre de la migración de destino (¡el nombre de la 0ª migración no existe antes de que se aplique una migración!). Entonces, en ese caso, debe usar el valor 0 (ordinal). Del mismo modo, si ha aplicado las migraciones A, B, C, D y E (en ese orden), el ordinal 1 debería referirse a A, el ordinal 2 debería referirse a B, y así sucesivamente. Entonces, para retroceder a B, puede usar:

Update-Database -TargetMigration:"B"

o

Update-Database -TargetMigration:2

Editar octubre de 2019:

De acuerdo con esta respuesta relacionada en una pregunta similar, el comando correcto es -Targetpara EF Core 1.1 mientras que -Migrationpara EF Core 2.0.

Jazimov
fuente
27
El nombre de la migración con índice 0 es $InitialDatabase.
MEMark
1
Gracias. ¿Hay algún valor $ (nombre) para referirse a otras posiciones de índice, como $ LatestDatabase, o algo así?
Jazimov
No lo sé. No he podido encontrar ninguno simplemente buscando en Google. ¿Tal vez navegar por el código fuente de EF los revelaría?
MEMark
3
Para su información, acabamos de encontrarnos con esto y estábamos buscando hacer lo mismo que OP ... usarlo ls variable:*parece ser $InitialDatabasesimplemente una variable de PowerShell definida como 0, no hay otras definidas, incluso en el código fuente EF actual. Y, get-migrations no devuelve nada, solo escribe en la consola, por lo que no puede iterar sobre los objetos devueltos ...
DrewJordan
1
Esta debería ser la respuesta
WtFudgE
76

En EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

donde 20161012160749_AddedOrderToCoursees un nombre de migración al que desea revertir.

MaciejLisCK
fuente
3
¡JOYA! Me tomó un tiempo encontrar esta respuesta (ya que la han cambiado para .NET Core). Definitivamente vale la pena un voto a favor!
HockeyJ
44
No necesita incluir la fecha / hora. Solo puedes poner el nombre.
Richard Marskell - Drackir
1
Esto no funciona para mí ... dirá "Listo" pero todas las migraciones después de la que especifico aún permanecen. Y ninguno de los códigos "inactivos" en ninguna de esas migraciones se ha ejecutado.
egmfrs
también se puede volver a una migración específica como esa: Actualización-Base de datos -Migración: "AddedOrderToCourse" Especialmente cuando se usan espacios en blanco en los nombres de migración, esta es la forma de hacerlo. (es decir, Actualización-Base de datos -Migración "Orden agregada al curso")
SwissCoder
13

La solucion es:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess
Max
fuente
10
Esto ya se dijo en la pregunta, el autor de la pregunta ya lo sabía. No veo cómo esto ayuda, ¿tal vez podrías aclararlo?
ANeves
Esta respuesta es más concisa. TY Max!
andreikashin
4

Recordatorio adicional:

Si tiene varios tipos de configuración, debe especificar el [ConfigurationName]

Update-Database -Configurationtypename [ConfigurationName] -TargetMigration [MigrationName]
Amós
fuente
3

En EF Core, puede ingresar el comando Remove-Migrationen la consola del administrador de paquetes después de haber agregado su migración errónea.

La consola sugiere que lo haga si su migración puede implicar una pérdida de datos:

Se andamio una operación que puede resultar en la pérdida de datos. Revise la migración para mayor precisión. Para deshacer esta acción, use Remove-Migration.

Sean Saúl Astrakhan
fuente
3
update-database 0

Advertencia : ¡Esto revertirá TODAS las migraciones en EFCore! Por favor, use con cuidado :)

mattylantz
fuente
2

Descubrí que esto funciona cuando se ejecuta en la consola de Package Manager:

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

Podría crear un script que lo haga más fácil.

Alex Dresko
fuente
1

Estoy usando EntityFrameworkCore y uso la respuesta de @MaciejLisCK. Si tiene múltiples contextos de base de datos, también deberá especificar el contexto agregando el parámetro de contexto, por ejemplo:

Update-Database 201207211340509_MyMigration -context myDBcontext

(¿Dónde 201207211340509_MyMigrationestá la migración a la que desea revertir y myDBcontextes el nombre de su contexto DB?)

Chris Halcrow
fuente
0

En caso de que exista la posibilidad de que dataloss EF no complete el comando de actualización de la base de datos, ya que AutomaticMigrationDataLossAllowed = false de manera predeterminada, roolbacks la acción a menos que la ejecute con el parámetro -force .

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

o

Update-Database TargetMigration:Your_Migration_Index -force
hhk
fuente