Откат платформы Entity Framework и удаление плохой миграции

Я использую EF 6.0 для своего проекта на С# с ручными миграциями и обновлениями. У меня около 5 миграций в базе данных, но я понял, что последняя миграция плохая, и я не хочу этого. Я знаю, что могу вернуться к предыдущей миграции, но когда я добавляю новую (фиксированную) миграцию и запускаю Update-Database, применяется даже плохая миграция.

Я пытался отменить предыдущую миграцию и удалить файл с плохой миграцией. Но затем, когда я пытаюсь добавить новую миграцию, я получаю сообщение об ошибке при обновлении базы данных, потому что файл миграции поврежден (более конкретно, первая строка кода переименовывает таблицу A в B и является следующей строкой, EF пытается обновить таблицу с помощью имя A - возможно, это некоторая ошибка EF).

Есть ли какой-то запрос, который я могу запустить, что бы сказать EF что-то вроде "Забыть последнюю миграцию, как она никогда не существовала, это было плохо"? Что-то вроде Remove-Migration.

Edit1 Я нашел решение, подходящее для меня. Изменение модели до хорошего состояния и запуск Add-Migration TheBadMigration -Force. Это приведет к восстановлению последней, а не миграции.

Во всяком случае, это все еще не полностью отвечает на исходный вопрос. Если я UpdateDatabase для плохой миграции, я не нашел хороший способ отката и создания новой миграции, за исключением плохой.

Спасибо

Ответ 1

У вас есть 2 варианта:

  • Вы можете взять Down из плохой миграции и поместить ее в новую миграцию (вам также необходимо будет внести последующие изменения в модель). Это эффективно сводится к лучшей версии.

    Я использую этот параметр для вещей, которые перешли в несколько сред.

  • Другой вариант - фактически запустить Update-Database –TargetMigration: TheLastGoodMigration для вашей развернутой базы данных, а затем удалить миграцию из вашего решения. Это своего рода альтернатива hulk smash и требует, чтобы это выполнялось против любой базы данных, развернутой с плохой версией.

    Примечание., чтобы отменить миграцию, вы можете использовать Add-Migration [existingname] -Force. Это, однако, перезапишет существующую миграцию, поэтому обязательно сделайте это, только если вы удалили существующую миграцию из базы данных. Это делает то же самое, что удаление существующего файла миграции и запуск add-migration

    Я использую эту опцию при разработке.

Ответ 2

Как показывает вопрос, это относится к миграции в среде типа разработки, которая еще не была выпущена.

Эта проблема может быть решена с помощью следующих шагов: восстановить вашу базу данных до последней удачной миграции, удалить неудачную миграцию из вашего проекта Entity Framework, сгенерировать новую миграцию и применить ее к базе данных. Примечание. Судя по комментариям, эти точные команды могут больше не применяться, если вы используете EF Core.

Шаг 1. Восстановление предыдущей миграции

Если вы еще не применили свою миграцию, вы можете пропустить эту часть. Чтобы восстановить схему базы данных до предыдущей точки, введите команду Update-Database с параметром -TargetMigration, указав последний удачный перенос:

Update-Database –TargetMigration: <name of last good migration>

Чтобы получить имя последней удачной миграции, используйте команду "Get-Migrations", чтобы получить список имен миграции, которые были применены к вашей базе данных.

PM> Get-Migrations
Retrieving migrations that have been applied to the target database.
201508242303096_Bad_Migration
201508211842590_The_Migration_applied_before_it
201508211440252_And_another

В этом списке сначала отображаются самые последние примененные миграции. Выберите миграцию, которая происходит в списке после того, на который вы хотите понизить рейтинг, т.е. тот, который применен перед тем, на который вы хотите понизить рейтинг. Теперь выполните обновление базы данных.

Update-Database –TargetMigration: "<the migration applied before it>"

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

Шаг 2. Удалить миграцию из проекта

Теперь вы можете удалить неудачную миграцию из папки "Миграции" вашего проекта EF. Теперь вы можете создать новую миграцию и применить ее к базе данных.

Шаг 3. Добавьте новую миграцию

add-migration "new migration"

Шаг 4. Примените миграцию к базе данных

update-database

Ответ 3

Для тех, кто использует EF Core с ASP.NET Core v1.0.0, у меня была аналогичная проблема, и для ее исправления использовались следующие команды (сообщение @DavidSopko указывало мне в правильном направлении, но подробности немного отличаются для EF Core):

Update-Database <Name of last good migration>
Remove-Migration

Например, в моем текущем развитии команда стала

PM> Update-Database CreateInitialDatabase
Done.
PM> Remove-Migration
Done.
PM> 

Remove-Migration удалит последнюю миграцию, которую вы применили. Если у вас более сложный сценарий с несколькими миграциями для удаления (у меня было только 2, начальное и неправильное), я предлагаю вам протестировать шаги в фиктивном проекте.

В настоящее время не существует команды Get-Migrations в EF Core (v1.0.0), поэтому вы должны искать в своей папке миграции и быть знакомым с тем, что вы сделали. Однако есть приятная справочная команда:

PM> get-help entityframework

Обновление dastabase в VS2015 обозревателе объектов SQL Server, все мои данные были сохранены, и миграция, которую я хотел вернуть, исчезла:)

Первоначально я попробовал Remove-Migration сам по себе и нашел ошибку в ошибке:

System.InvalidOperationException: миграция "..." уже была применяется к базе данных. Не используйте его и повторите попытку. Если миграция был применен к другим базам данных, рассмотреть вопрос о возврате его изменений используя новую миграцию.

Уже есть предложения по улучшению этой формулировки, но я хотел бы, чтобы ошибка говорила примерно так:

Запустите Update-Database (последнее хорошее имя миграции), чтобы вернуть схему базы данных обратно в это состояние. Эта команда будет исключить все миграции, которые произошли после перенастройки, указанной в Обновление базы данных. Затем вы можете запустить Remove-Migration (имя миграции для удаления)

Результат из команды помощи EF Core:

 PM> get-help entityframework
                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\

TOPIC
    about_EntityFrameworkCore

SHORT DESCRIPTION
    Provides information about Entity Framework Core commands.

LONG DESCRIPTION
    This topic describes the Entity Framework Core commands. See https://docs.efproject.net for information on Entity Framework Core.

    The following Entity Framework cmdlets are included.

        Cmdlet                      Description
        --------------------------  ---------------------------------------------------
        Add-Migration               Adds a new migration.

        Remove-Migration            Removes the last migration.

        Scaffold-DbContext          Scaffolds a DbContext and entity type classes for a specified database.

        Script-Migration            Generates a SQL script from migrations.

        Update-Database             Updates the database to a specified migration.

        Use-DbContext               Sets the default DbContext to use.

SEE ALSO
    Add-Migration
    Remove-Migration
    Scaffold-DbContext
    Script-Migration
    Update-Database
    Use-DbContext

Ответ 4

Во-первых, обновите вашу последнюю совершенную миграцию с помощью этой команды:

Update-Database –TargetMigration

Пример:

Update-Database -20180906131107_xxxx_xxxx

А затем вручную удалите неиспользованную миграцию.

Ответ 5

Начиная с .NET Core 2.2, TargetMigration похоже, больше нет:

get-help Update-Database

NAME
    Update-Database

SYNOPSIS
    Updates the database to a specified migration.


SYNTAX
    Update-Database [[-Migration] <String>] [-Context <String>] [-Project <String>] [-StartupProject <String>] [<CommonParameters>]


DESCRIPTION
    Updates the database to a specified migration.


RELATED LINKS
    Script-Migration
    about_EntityFrameworkCore 

REMARKS
    To see the examples, type: "get-help Update-Database -examples".
    For more information, type: "get-help Update-Database -detailed".
    For technical information, type: "get-help Update-Database -full".
    For online help, type: "get-help Update-Database -online"

Так что это работает для меня сейчас:

Update-Database -Migration 20180906131107_xxxx_xxxx

А также (без переключателя -Migration):

Update-Database 20180906131107_xxxx_xxxx

В добавленной заметке вы больше не можете чистым образом удалять папки миграции, не отключая снимок модели. Так что, если вы усвоите этот сложный путь и в итоге получите пустую миграцию, в которой вы знаете, что должны быть изменения, вы можете запустить (без переключателей, необходимых для последней миграции):

Remove-migration

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

Ответ 6

Для EF 6 здесь одна строчка, если вы много работаете в процессе разработки. Просто обновите vars, а затем продолжайте использовать стрелку вверх в консоли диспетчера пакетов для полоскания и повторения.

$lastGoodTarget = "OldTargetName"; $newTarget = "NewTargetName"; Update-Database -TargetMigration "$lastGoodTarget" -Verbose; Add-Migration "$newTarget" -Verbose -Force

Почему это необходимо, спросите вы? Не уверен, к каким версиям EF6 это применимо, но если ваша новая цель миграции уже была применена, то использование "-Force" для повторной установки в Add-Migration фактически не будет повторной сборкой, а вместо этого создаст новый файл (это хорошая вещь, хотя, потому что вы не хотели бы потерять свой "вниз"). Приведенный выше фрагмент сначала выполняет 'Down', если необходимо, затем -Force работает правильно для повторной сборки лесов.

Ответ 7

Вы также можете использовать

Remove-Migration -Force

Это вернет и удалит последнюю примененную миграцию