Migrações EF: reverter a última aplicação de migração?

436

Parece uma tarefa muito comum, mas não consigo encontrar uma maneira fácil de fazer isso.

Quero desfazer a última migração aplicada. Eu esperava um comando simples, como

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

Em vez disso, tudo o que posso fazer é:

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"

(Pelo menos eu posso usar apenas o nome, pulando o carimbo de data e hora ...)

Existe uma maneira mais fácil?

Cristian Diaconescu
fonte
1
Triste, aqui estamos anos depois e ninguém realmente leu a pergunta.
Daniel ZA

Respostas:

161

A partir do EF 5.0, a abordagem descrita é a preferida. assim

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

ou usando suas migrações de exemplo

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Uma solução seria criar um script PS de wrapper que automatize as etapas acima. Além disso, sinta-se à vontade para criar uma solicitação de recurso para isso, ou melhor ainda, tente implementá-la! https://github.com/dotnet/ef6

Andrew Peters
fonte
4
Outro detalhe: se você já possui uma Migração Manual existente, mas percebeu que o método "Para baixo" realmente não reverte as coisas corretamente, basta editá-lo e salvá-lo, e execute novamente update-database -target. até retroceder corretamente. Modificar a migração manual após o fato - depois de a aplicar - não a transforma em algo que não pode ser editado.
Chris Moschini
1
Isso não funciona para mim. Tudo que eu vejo é "migração de destino especificado '-1' não existe.
tutiplain
2
@tutiplain Veja seu segundo bloco de código. Você citando o que ele deseja que exista, não o que existe.
Sinjai
qual é a maneira correta de fazer isso usando o comando dotnet? Desculpe, não encontrei na documentação ou estou perdendo alguma coisa. Tentei através entityframeworktutorial.net/efcore/… alguma sugestão?
Sijan Shrestha
Achei a solução, dotnet ef database update LastGoodMigrationno entanto, isso parece confuso, pois estou vindo de um nó em segundo plano e usando knex, sequlize, eles têm um comando para reverter a última alteração, existe algum comando para reverter a última ação aplicada ao banco de dados ?
Sijan Shrestha
415

Quero acrescentar alguns esclarecimentos a este tópico:

Update-Database -TargetMigration:"name_of_migration"

O que você está fazendo acima é dizer que deseja reverter todas as migrações ATÉ que fique com a migração especificada. Portanto, se você usa GET-MIGRATIONS e descobre que possui A, B, C, D e E, o uso desse comando reverte E e D para levá-lo a C:

Update-Database -TargetMigration:"C"

Além disso, a menos que alguém possa comentar o contrário, notei que você pode usar um valor ordinal e a opção -Target curta (assim, -Target é o mesmo que -TargetMigration). Se você deseja reverter todas as migrações e começar de novo, poderá usar:

Update-Database -Target:0

0, acima, reverteria mesmo a PRIMEIRA migração ( este é um comando destrutivo - saiba o que você está fazendo antes de usá-lo! ) - algo que você não pode fazer se usar a sintaxe acima que requer o nome de a migração de destino (o nome da 0ª migração não existe antes da aplicação da migração!). Portanto, nesse caso, você deve usar o valor 0 (ordinal). Da mesma forma, se você aplicou as migrações A, B, C, D e E (nessa ordem), o ordinal 1 deve se referir a A, o ordinal 2 deve se referir a B e assim por diante. Portanto, para reverter para B, você pode usar:

Update-Database -TargetMigration:"B"

ou

Update-Database -TargetMigration:2

Editar outubro de 2019:

De acordo com essa resposta relacionada a uma pergunta semelhante, o comando correto é -Targetpara o EF Core 1.1 enquanto -Migrationpara o EF Core 2.0.

Jazimov
fonte
27
O nome da migração com o índice 0 é $InitialDatabase.
MEMark
1
Obrigado. Existem valores $ (name) para se referir a outras posições do índice, como $ LatestDatabase, ou algo assim?
precisa saber é o seguinte
Eu não sei. Não consegui encontrar nada pesquisando no Google. Talvez a navegação no código fonte da EF os revele?
MEMark
3
FYI, acabamos de descobrir isso e estávamos procurando fazer a mesma coisa que OP ... usando ls variable:*isso parece $InitialDatabasesimplesmente uma variável do PowerShell definida como 0, não há outras definidas, mesmo no código-fonte EF atual. E, obter-migrações não retorna nada, ele só escreve para o console, então você não pode repetir os objetos retornados ...
DrewJordan
1
Esta deve ser a resposta
WtFudgE
76

Em EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

onde 20161012160749_AddedOrderToCourseé um nome de migração para o qual você deseja reverter.

MaciejLisCK
fonte
3
GEMA! Levei um tempo para encontrar esta resposta (como eles a mudaram para o .NET Core). Definitivamente vale a pena votar!
HockeyJ
4
Você não precisa incluir a data / hora. Você pode simplesmente colocar o nome.
Richard Marskell - Drackir
1
Isso não funciona para mim ... dirá "Concluído", mas todas as migrações após a especificada ainda permanecem. E nenhum código "Inativo" em nenhuma dessas migrações foi executado.
egmfrs 21/03
também é possível voltar a uma migração específica como essa: Update-Database -Migration: "AddedOrderToCourse" Especialmente ao usar espaços em branco nos nomes de migração, esta é a maneira de fazê-lo. (ou seja, Update-Database -Migration "Adicionado pedido ao curso")
SwissCoder
13

A solução é:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess
Máx.
fonte
10
Isso já foi dito na pergunta, o autor da pergunta já sabia disso. Não vejo como isso ajuda, talvez você possa deixar isso mais claro?
ANeves
esta resposta é mais concisa. TY Max!
precisa saber é o seguinte
4

Lembrete adicional:

Se você tiver vários tipos de configuração, precisará especificar o [Nome_da_Configuração]

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

No EF Core, você pode inserir o comando Remove-Migrationno console do gerenciador de pacotes após adicionar sua migração incorreta.

O console sugere que você faça isso se sua migração envolver uma perda de dados:

Foi montada uma operação que pode resultar na perda de dados. Revise a migração para obter precisão. Para desfazer essa ação, use Remove-Migration.

Sean Saúl Astrakhan
fonte
3
update-database 0

Aviso : Isso reverterá TODAS as migrações no EFCore! Por favor, use com cuidado :)

mattylantz
fonte
2

Descobri que isso funciona quando executado no console do gerenciador de pacotes:

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

Você pode criar um script que facilite.

Alex Dresko
fonte
1

Estou usando EntityFrameworkCore e uso a resposta de @MaciejLisCK. Se você tiver vários contextos de banco de dados, também precisará especificar o contexto adicionando o parâmetro context, por exemplo:

Update-Database 201207211340509_MyMigration -context myDBcontext

(onde 201207211340509_MyMigrationestá a migração para a qual você deseja reverter e myDBcontexté o nome do seu contexto de banco de dados)

Chris Halcrow
fonte
0

Caso exista a possibilidade de o dataloss EF não concluir o comando update-database, pois AutomaticMigrationDataLossAllowed = false por padrão e roolbacka a ação, a menos que você a execute com o parâmetro -force .

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

ou

Update-Database TargetMigration:Your_Migration_Index -force
hhk
fonte