EF Migrations: откат последней примененной миграции?

436

Это выглядит как обычная задача, но я не могу найти простой способ сделать это.

Я хочу отменить последнюю примененную миграцию. Я бы ожидал простую команду, как

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

Вместо этого все, что я могу придумать, это:

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"

(По крайней мере, я могу использовать только имя, пропуская метку времени ...)

Есть ли более простой способ?

Кристиан Дьяконеску
источник
1
Грустно, вот мы годы спустя и никто на самом деле не читал вопрос.
Даниэль З.А.

Ответы:

162

Начиная с EF 5.0, описанный вами подход является предпочтительным. Так

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

или используя ваш пример миграций

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Одним из решений было бы создание сценария PS-оболочки, который автоматизирует описанные выше шаги. Кроме того, не стесняйтесь создавать запрос функции для этого, или еще лучше, попробуйте его реализовать! https://github.com/dotnet/ef6

Эндрю Питерс
источник
4
Еще одна деталь: если у вас есть существующая ручная миграция, к которой нужно вернуться, но вы поняли, что ваш метод «Down» на самом деле не откатывает вещи должным образом, вы можете просто отредактировать и сохранить его, а затем повторно запустить update-database -target. пока он не откатится должным образом. Изменение ручной миграции после факта - после того, как вы уже применили ее - не превращает ее в то, что нельзя редактировать.
Крис Москини
1
Это не работает для меня. Все, что я получаю, это "указанная целевая миграция" -1 "не существует.
tutiplain
2
@tutiplain Посмотрите на его второй блок кода. Вы цитируете то, что он желал, а не то, что существует.
Синджай
Как правильно сделать это с помощью команды dotnet? Извините, я не смог найти в документации или я что-то упустил. Пробовал через entityframeworktutorial.net/efcore/… какие-либо предложения?
Сиян Шреста
Я нашел решение, dotnet ef database update LastGoodMigrationоднако это сбивает с толку, так как я пришел из фона узла и использую knex, sequlize, у них есть команда, чтобы отменить последнее изменение, есть ли команда, чтобы отменить последнее действие, которое было применено к базе данных ?
Сиян Шреста
415

Я хочу добавить некоторые пояснения к этой теме:

Update-Database -TargetMigration:"name_of_migration"

То, что вы делаете выше, говорит, что вы хотите откатить все миграции до тех пор, пока у вас не останется указанная миграция. Таким образом, если вы используете GET-MIGRATIONS и обнаружите, что у вас есть A, B, C, D и E, то с помощью этой команды откат E и D приведет вас к C:

Update-Database -TargetMigration:"C"

Кроме того, если кто-то не может прокомментировать обратное, я заметил, что вы можете использовать порядковое значение и короткий ключ -Target (таким образом, -Target - это то же самое, что и -TargetMigration). Если вы хотите откатить все миграции и начать заново, вы можете использовать:

Update-Database -Target:0

0, выше, приведет к откату даже ПЕРВОЙ миграции ( это деструктивная команда - убедитесь, что вы знаете, что делаете, прежде чем ее использовать! ) - что вы не сможете сделать, если используете приведенный выше синтаксис, требующий имени целевая миграция (имя 0-й миграции не существует до применения миграции!). Так что в этом случае вы должны использовать значение 0 (порядковый номер). Аналогично, если вы применили миграции A, B, C, D и E (в этом порядке), то порядковый номер 1 должен ссылаться на A, порядковый номер 2 должен ссылаться на B и так далее. Таким образом, для отката на B вы можете использовать либо:

Update-Database -TargetMigration:"B"

или

Update-Database -TargetMigration:2

Изменить октябрь 2019 года:

Согласно этому связанному ответу на аналогичный вопрос, правильная команда -Targetдля EF Core 1.1, в то время как -Migrationдля EF Core 2.0.

Jazimov
источник
27
Имя миграции с индексом 0 - $InitialDatabase.
MEMark
1
Спасибо. Существуют ли значения $ (name) для ссылки на другие позиции индекса, такие как $ LatestDatabase или что-то в этом роде?
Джазимов
Я не знаю. Я не смог найти ни одного, просто прибегая к помощи. Может быть, просмотр исходного кода EF покажет их?
MEMark
3
К вашему сведению, мы только что натолкнулись на это и искали сделать то же самое, что и OP ... используя ls variable:*его, похоже, $InitialDatabaseэто просто переменная PowerShell, определенная как 0, другие не определены, даже в текущем исходном коде EF. И get-migrations ничего не возвращает, он только записывает в консоль, поэтому вы не можете перебирать возвращаемые объекты ...
DrewJordan
1
Это должен быть ответ
WtFudgE
76

В EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

где 20161012160749_AddedOrderToCourseимя миграции, к которой вы хотите выполнить откат.

MaciejLisCK
источник
3
GEM! Мне потребовалось некоторое время, чтобы найти этот ответ (поскольку они изменили его для .NET Core). Определенно стоит воздержаться!
HockeyJ
4
Вам не нужно указывать дату / время. Вы можете просто вставить имя.
Ричард Марскелл - Дракир
1
Это не работает для меня ... он скажет "Готово", но все миграции после того, который я указал, все еще остаются. И ни один из кодов «Down» ни в одной из этих миграций не был выполнен.
egmfrs
Можно также вернуться к определенной миграции, например: Update-Database -Migration: "AddedOrderToCourse". Особенно при использовании пробелов в именах миграции, это способ сделать это. (т. е. Update-Database -Migration «Добавлен порядок в курс»)
SwissCoder
13

Решение:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess
Максимум
источник
10
Об этом уже сказано в вопросе, аскер это уже знал. Я не понимаю, как это помогает, может быть, вы могли бы сделать это яснее?
Ноябрь
этот ответ является более кратким. TY Макс!
Андрейкашин
4

Дополнительное напоминание:

Если у вас несколько типов конфигурации, вам нужно указать [ConfigurationName]

Update-Database -Configurationtypename [ConfigurationName] -TargetMigration [MigrationName]
амосс
источник
3

В EF Core вы можете ввести команду Remove-Migrationв консоли диспетчера пакетов после добавления ошибочной миграции.

Консоль предлагает вам сделать это, если ваша миграция может привести к потере данных:

Была создана операция, которая может привести к потере данных. Пожалуйста, проверьте точность миграции. Чтобы отменить это действие, используйте Remove-Migration.

Шон Сауль Астрахань
источник
3
update-database 0

Предупреждение : Это откатит ВСЕ миграции в EFCore! Пожалуйста, используйте с осторожностью :)

mattylantz
источник
2

Я обнаружил, что это работает при запуске в консоли диспетчера пакетов:

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

Вы можете создать сценарий, который делает это проще.

Алекс Дреско
источник
1

Я использую EntityFrameworkCore и использую ответ @MaciejLisCK. Если у вас несколько контекстов БД, вам также необходимо указать контекст, добавив параметр контекста, например:

Update-Database 201207211340509_MyMigration -context myDBcontext

(где 201207211340509_MyMigrationнаходится миграция, к которой вы хотите вернуться, и myDBcontextимя контекста вашей БД)

Крис Хэлкроу
источник
0

В случае, если есть вероятность, что dataloss EF не выполнит команду update-database, поскольку AutomaticMigrationDataLossAllowed = false по умолчанию и выполнит откат действия, если вы не запустите его с параметром -force .

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

или

Update-Database TargetMigration:Your_Migration_Index -force
HHK
источник