Відкат Entity Framework та усунення поганої міграції


174

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

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

Чи є якийсь запит, який я можу запустити, який би сказав EF щось на кшталт "Забудьте останню міграцію, як ніколи не існувало, це було погано"? Щось на кшталт Remove-Migration.

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

У всякому разі, це все ще не відповідає повністю на початкове запитання. Якщо я оновив базу даних до поганої міграції, я не знайшов хорошого способу відкоту та створення нової міграції, виключаючи погану.

Дякую


Мені довелося перезапустити візуальну студію, і тоді вона почала справно працювати. Зі мною це вже траплялося кілька разів, завжди після того, як возитися з міграціями, фактично не оновлюючи базу даних, тому з інструментами там відбувається щось дивне.
Андрій Двойнос

Відповіді:


167

У вас є 2 варіанти:

  • Ви можете взяти Даун від поганої міграції та ввести її в нову міграцію (вам також потрібно буде внести подальші зміни в модель). Це ефективно згортається до кращої версії.

    Я використовую цю опцію для речей, які перейшли в декілька середовищ.

  • Інший варіант - реально працювати Update-Database –TargetMigration: TheLastGoodMigrationз розгорнутою базою даних, а потім видалити міграцію зі свого рішення. Це свого роду альтернатива hulk smash і вимагає цього виконувати проти будь-якої бази даних, розгорнутої з поганою версією.

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

    Я використовую цей варіант під час розробки.


1
Варіант забивання халка не працює. Я ще не застосував погану міграцію до бази даних. Я спробував, але це не спрацювало, тому що назви таблиць я вказав у оригінальному питанні. Перший варіант мені не дуже подобається, тому що схоже, що мені доведеться змінити код міграції. Якщо я зроблю це погано, можу все це зламати.
Мартін Брабек

8
Якщо ви ще не застосували погану міграцію, то ніщо не зупинить вас: або видалити її, і повторно розгорнути або виправити порушену міграцію.
Не любив

4
"Hulk smash" - це відповідь, він працює для мене під час розвитку, і я хочу додати щось до міграції, яку я пропустив. Я думаю, що причини, які не працювали для Мартіна, не пов'язані (або, ймовірно, пов'язані зі зміною схеми бази даних вручну)
rethenhouser2

1
@BenRethmeier як загальне правило, я використовую варіант hulk smash лише під час розвитку. У продажі я завжди створюю нову міграцію, щоб виправити проблему. Причина полягає в тому, що вам потрібно вручну втручатися, якщо ви знижуєте базу даних. Мені не подобається нічого, що потребує ручного втручання у продажі.
Не любив

1
HULK SMASH !!!! --- Я намагався бути приємним, але EF не грав - я повернувся до останнього відомого - (Резервне копіювання файлів міграції) Видалено, додано міграцію - Force - Перейменовано на попередній і скопійовано код. Оновити базу даних, потім додано друга міграція так само - без помилок - повернемося до нормальної норми
Трачі

127

Оскільки питання вказує, це стосується міграції у середовищі типу розробки, яка ще не була випущена.

Цю проблему можна вирішити на цих етапах: відновіть базу даних до останньої доброї міграції, видаліть погану міграцію з вашого проекту 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.

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

Усі міграції, застосовані після зазначеної, будуть зменшені для того, щоб почати з останньої міграції, застосованої спочатку.

Крок 2: Видаліть міграцію з проекту

remove-migration name_of_bad_migration

Якщо remove-migrationкоманда недоступна у вашій версії Entity Framework, видаліть файли небажаної міграції папку «Міграції» проекту EF вручну. На даний момент ви можете створити нову міграцію та застосувати її до бази даних.

Крок 3. Додайте нову міграцію

add-migration my_new_migration

Крок 4: Застосуйте міграцію до бази даних

update-database

6
Завдяки EF Core здається, що Get-Migrations було видалено.
Кевін Бертон

1
Крок2! - Дуже корисна функція. Як згадував @KevinBurton А потім add-migration "new migration",update-database
Олександр Фролов

2
Update-Database –migration: "<міграція застосована до неї>" @David Sopko
Fuat

Дякую @AlexanderFrolov Я оновив рішення, щоб відобразити ваші коментарі.
Давид Сопко

1
нам потрібно використовувати видалити-міграцію після кроку 2
Рахул

55

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

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

Наприклад, у моїй теперішній розробці командою стала

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

Видалення-міграція видалить останню застосовану вами міграцію. Якщо у вас є складніший сценарій з декількома міграціями для видалення (у мене було лише 2, початковий і поганий), я пропоную вам протестувати етапи підробленого проекту.

Наразі в EF Core (v1.0.0) не існує команди Get-Migrations, тому ви повинні заглянути в папку міграцій і бути знайомим з тим, що ви зробили. Однак є приємна команда довідки:

PM> get-help entityframework

Оновлення бази даних у VS2015 SQL Server Object Explorer, всі мої дані збереглись, і міграція, яку я хотів відновити, зникла :)

Спочатку я спробував Remove-Migration сам і виявив, що команда помилок плутає:

System.InvalidOperationException: Міграція '...' вже застосована до бази даних. Скасуйте його та спробуйте ще раз. Якщо міграція застосована до інших баз даних, спробуйте відновити її зміни за допомогою нової міграції.

Вже є пропозиції щодо вдосконалення цього формулювання, але я хотів би помилку сказати щось подібне:

Запустіть Update-Database (останнє гарне ім’я міграції), щоб повернути схему бази даних до цього стану. Ця команда не застосовуватиме всі міграції, що відбулися після міграції, вказаної на 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

6

Ви також можете використовувати

Remove-Migration -Force

Це відновить та видалить останню застосовану міграцію


4

По-перше, оновіть останню ідеальну міграцію за допомогою цієї команди:

Update-Database TargetMigration

Приклад:

Update-Database -20180906131107_xxxx_xxxx

Потім видаліть невикористану міграцію вручну.


2
це повинно бути: Update-Database -TargetMigration 20180906131107_xxxx_xxxx
Elger Mensonides

Update-Database 20180906131107_xxxx_xxxx(без дефісу) працював на мене. Не працює жодна версія TargetMigrationперемикача. Ці команди здаються рухомою ціллю (тобто змінювати їх у кожній версії)?
Сума

3

Станом на .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

Це очистить безлад і поверне вас туди, де вам належить бути, хоча останню папку міграції видалено вручну.


0

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

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

Чому це потрібно запитати? Не впевнений, для яких версій EF6 це застосовується, але якщо ваша нова міграційна ціль уже застосована, то використання "-Force" для повторного риштування в Add-Migration насправді не переробить лісу, а натомість створить новий файл (це добре річ, хоча тому, що ви не хочете втрачати своє "Вниз"). Вищенаведений фрагмент при необхідності спочатку робить "Вниз", потім - Форс працює належним чином, щоб повторно поставити ліси.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.