Migracje EF: migracja ostatnio zastosowana?


435

To wygląda na bardzo częste zadanie, ale nie mogę znaleźć łatwego sposobu na wykonanie tego.

Chcę cofnąć ostatnią zastosowaną migrację. Spodziewałbym się prostego polecenia, na przykład

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

Zamiast tego mogę tylko wymyślić:

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"

(Przynajmniej mogę użyć tylko nazwy, pomijając znacznik czasu ...)

Czy istnieje prostszy sposób?


1
Niestety, jesteśmy lata później i nikt tak naprawdę nie przeczytał pytania.
Daniel ZA

Odpowiedzi:


160

Od wersji 5.0 5.0 podejście, które opisujesz, jest preferowanym sposobem. Więc

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

lub korzystając z przykładowych migracji

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Jednym z rozwiązań byłoby utworzenie otoki PS skryptu, który automatyzuje powyższe kroki. Ponadto możesz utworzyć prośbę o tę funkcję lub jeszcze lepiej, wypróbuj ją! https://github.com/dotnet/ef6


4
Kolejny szczegół: jeśli masz już istniejącą ręczną migrację, do której musisz przywrócić, ale zdałeś sobie sprawę, że twoja metoda „w dół” tak naprawdę nie przywraca poprawnie rzeczy, możesz ją po prostu edytować i zapisać, a następnie ponownie uruchomić aktualizację bazy danych-cel. , dopóki nie zwinie się poprawnie. Modyfikacja ręcznej migracji po fakcie - po jej zastosowaniu - nie zmienia jej w coś, co nie może być edytowane.
Chris Moschini,

1
To mi nie działa. Wszystko, co otrzymuję, to „określona migracja docelowa” -1 ”nie istnieje.
tutiplain

2
@tutiplain Spójrz na jego drugi blok kodu. Cytujesz, co chciałby, żeby istniało, a nie to, co istnieje.
Sinjai

jaki jest prawidłowy sposób wykonania tego polecenia za pomocą polecenia dotnet? Niestety nie mogłem znaleźć w dokumentacji lub czegoś brakuje. Próbowałeś przez entityframeworktutorial.net/efcore/… jakieś sugestie?
Sijan Shrestha

Znalazłem rozwiązanie, dotnet ef database update LastGoodMigrationjednak wydaje się to mylące, ponieważ wychodzę z tła węzła i za pomocą knex, sequlize, mają polecenie cofnięcia ostatniej zmiany, czy istnieje polecenie cofnięcia ostatniej akcji, która została zastosowana do bazy danych ?
Sijan Shrestha

415

Chcę dodać wyjaśnienie do tego wątku:

Update-Database -TargetMigration:"name_of_migration"

To, co robisz powyżej, mówi, że chcesz wycofać wszystkie migracje, dopóki nie pozostaniesz z określoną migracją. Zatem jeśli użyjesz GET-MIGRATIONS i okaże się, że masz A, B, C, D i E, to użycie tego polecenia spowoduje cofnięcie E i D, aby dostać się do C:

Update-Database -TargetMigration:"C"

Ponadto, chyba że ktokolwiek może skomentować inaczej, zauważyłem, że można użyć wartości porządkowej i krótkiego przełącznika -Target (a zatem -Target jest taki sam jak -TargetMigration). Jeśli chcesz wycofać wszystkie migracje i zacząć od nowa, możesz użyć:

Update-Database -Target:0

0 powyżej cofnęłoby nawet PIERWSZĄ migrację ( jest to destrukcyjne polecenie - upewnij się, że wiesz, co robisz przed użyciem! ) - coś, czego nie możesz zrobić, jeśli użyjesz powyższej składni, która wymaga nazwy migracja docelowa (nazwa 0 migracji nie istnieje przed zastosowaniem migracji!). W takim przypadku musisz użyć wartości 0 (porządkowej). Podobnie, jeśli zastosowałeś migracje A, B, C, D i E (w tej kolejności), wówczas porządek 1 powinien odnosić się do A, porządek 2 powinien odnosić się do B i tak dalej. Aby przywrócić B, możesz użyć:

Update-Database -TargetMigration:"B"

lub

Update-Database -TargetMigration:2

Edytuj październik 2019:

Zgodnie z tą pokrewną odpowiedzią na podobne pytanie, poprawne polecenie dotyczy -TargetEF Core 1.1, podczas gdy dotyczy to -MigrationEF Core 2.0.


27
Nazwa migracji o indeksie 0 to $InitialDatabase.
UWAGA

1
Dzięki. Czy istnieją jakieś wartości $ (name) odnoszące się do innych pozycji indeksu, takich jak $ LatestDatabase, czy coś takiego?
Jazimov

Nie wiem Nie udało mi się go znaleźć przez zwykłe google. Może przeglądanie kodu źródłowego EF je ujawni?
MEMark,

3
Do Twojej wiadomości, właśnie natrafiliśmy na to i chcieliśmy zrobić to samo co OP ... używając ls variable:*tego wygląda $InitialDatabaseto po prostu zmienna PowerShell zdefiniowana jako 0, nie ma żadnych innych zdefiniowanych, nawet w bieżącym kodzie źródłowym EF. A migracje get nic nie zwracają, tylko zapisują na konsoli, więc nie można iterować po zwróconych obiektach ...
DrewJordan,

1
To powinna być odpowiedź
WtFudgE

76

W EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

gdzie 20161012160749_AddedOrderToCoursejest nazwa migracji, do której chcesz przywrócić.


3
KLEJNOT! Znalezienie tej odpowiedzi zajęło mi trochę czasu (ponieważ zmieniono ją dla platformy .NET Core). Zdecydowanie warte pochwały!
HockeyJ

4
Nie musisz podawać daty / godziny. Możesz po prostu wpisać nazwę.
Richard Marskell - Drackir

1
To nie działa dla mnie ... powie „Gotowe”, ale wszystkie migracje po tej, którą określiłem, nadal pozostają. I żaden z kodów „Down” w żadnej z tych migracji nie został wykonany.
egmfrs

można także wrócić do konkretnej migracji w ten sposób: Update-Database -Migration: „addedOrderToCourse” Zwłaszcza w przypadku używania pustych nazw w nazwach migracji, jest to sposób na zrobienie tego. (tj. aktualizacja bazy danych-migracja „Dodano zamówienie do kursu”)
SwissCoder

13

Rozwiązaniem jest:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess

10
Jest to już powiedziane w pytaniu, pytający już to wiedział. Nie rozumiem, jak to pomaga, może mógłbyś to wyjaśnić?
ANeves

ta odpowiedź jest bardziej zwięzła. TY Max!
andreikashin

4

Dodatkowe przypomnienie:

Jeśli masz wiele typów konfiguracji, musisz podać [ConfigurationName]

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

3

W EF Core możesz wpisać polecenie Remove-Migrationw konsoli menedżera pakietów po dodaniu błędnej migracji.

Konsola sugeruje, aby to zrobić, jeśli migracja może wiązać się z utratą danych:

Rusztowano operację, która może spowodować utratę danych. Sprawdź dokładność migracji. Aby cofnąć tę czynność, użyj opcji Usuń migrację.


3
update-database 0

Ostrzeżenie : spowoduje to wycofanie WSZYSTKICH migracji w EFCore! Proszę używać ostrożnie :)


2

Stwierdziłem, że działa to po uruchomieniu w konsoli Menedżera pakietów:

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

Możesz stworzyć skrypt, który to ułatwi.


1

Korzystam z EntityFrameworkCore i korzystam z odpowiedzi @MaciejLisCK. Jeśli masz wiele kontekstów DB, musisz także określić kontekst, dodając parametr kontekstu, np .:

Update-Database 201207211340509_MyMigration -context myDBcontext

(gdzie 201207211340509_MyMigrationjest migracja, do której chcesz przywrócić i myDBcontextnazwa twojego kontekstu DB)



0

W przypadku, gdy istnieje możliwość, że utrata danych EF nie wykona polecenia update-database, ponieważ AutomaticMigrationDataLossAllowed = false domyślnie, i wycofuje akcję, chyba że uruchomisz ją z parametrem -force .

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

lub

Update-Database TargetMigration:Your_Migration_Index -force
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.