Entity Framework 롤백 및 잘못된 마이그레이션 제거


174

수동 마이그레이션 및 업데이트와 함께 C #에서 프로젝트에 EF 6.0을 사용하고 있습니다. 데이터베이스에 약 5 개의 마이그레이션이 있지만 마지막 마이그레이션이 잘못되어 원하지 않는다는 것을 깨달았습니다. 이전 마이그레이션으로 롤백 할 수 있지만 새 (고정) 마이그레이션을 추가하고 Update-Database를 실행하면 잘못된 마이그레이션도 적용됩니다.

이전 마이그레이션으로 롤백하려고하고 마이그레이션이 잘못된 파일을 삭제하려고했습니다. 그러나 새 마이그레이션을 추가하려고하면 마이그레이션 파일이 손상되어 데이터베이스를 업데이트 할 때 오류가 발생합니다 (특히 코드의 첫 줄은 테이블 이름을 B로 바꾸고 다음 줄은 EF가 이름 A-어쩌면 EF 버그 일 수도 있습니다).

실행할 수있는 쿼리가 있습니까? "EF에"마지막 마이그레이션은 존재하지 않았으므로 잘못되었습니다. " Remove-Migration과 같은 것.

Edit1 나에게 적합한 솔루션을 찾았습니다. 모델을 양호한 상태로 변경하고 실행 Add-Migration TheBadMigration -Force합니다. 이것은 적용되지 않은 마지막 마이그레이션을 다시 스캐 폴드합니다.

어쨌든 이것은 여전히 ​​원래 질문에 완전히 대답하지는 않습니다. 데이터베이스를 잘못된 마이그레이션으로 업데이트하면 나쁜 마이그레이션을 제외하고 롤백하고 새 마이그레이션을 만드는 방법을 찾지 못했습니다.

감사


Visual Studio를 다시 시작한 다음 제대로 작동하기 시작했습니다. 이것은 실제로 데이터베이스를 업데이트하지 않고 마이그레이션을 엉망으로 만든 후에 이미 두 번 발생했습니다. 그래서 툴링에 이상한 일이 있습니다.
Andrei Dvoynos

답변:


167

두 가지 옵션이 있습니다.

  • 잘못된 마이그레이션에서 다운을 수행하여 새 마이그레이션으로 전환 할 수 있습니다 (모델에 대한 후속 변경도 수행해야 함). 이것은 효과적으로 더 나은 버전으로 롤업하고 있습니다.

    여러 환경으로 이동 한 환경에서이 옵션을 사용합니다.

  • 다른 옵션은 실제로 Update-Database –TargetMigration: TheLastGoodMigration배포 된 데이터베이스에 대해 실행 한 다음 솔루션에서 마이그레이션을 삭제하는 것입니다. 이것은 일종의 헐크 스매시 대안이며 나쁜 버전으로 배포 된 모든 데이터베이스에 대해 수행해야합니다.

    참고 : 마이그레이션을 다시 스캐 폴딩하려면을 사용할 수 있습니다 Add-Migration [existingname] -Force. 그러나 이는 기존 마이그레이션을 덮어 쓰므로 데이터베이스에서 기존 마이그레이션을 제거한 경우에만 수행하십시오. 기존 마이그레이션 파일을 삭제하고 실행하는 것과 동일한 작업을 수행합니다.add-migration

    개발하는 동안이 옵션을 사용합니다.


1
헐크 스매시 옵션이 작동하지 않습니다. 데이터베이스에 잘못된 마이그레이션을 아직 적용하지 않았습니다. 원래 질문에 지정한 테이블 이름 때문에 시도했지만 작동하지 않았습니다. 첫 번째 옵션은 마이그레이션 코드를 변경 해야하는 것처럼 보이기 때문에별로 좋아하지 않습니다. 내가 잘못하면 모든 것을 무너 뜨릴 수 있습니다.
Martin Brabec

8
잘못된 마이그레이션을 아직 적용하지 않은 경우 삭제를 중지하고 다시 스캐 폴딩하거나 손상된 마이그레이션을 수정하는 것이 없습니다.
사랑하지 않는

4
'허크 ​​스매시'가 답입니다. 개발할 때 저에게 효과적이며 내가 놓친 마이그레이션에 무언가를 추가하고 싶습니다. Martin에서 작동하지 않는 이유는 서로 관련이 없거나 데이터베이스 스키마를 수동으로 변경하는 것과 관련이 있다고 생각합니다.
rethenhouser2

1
@BenRethmeier는 일반적으로 개발하는 동안에 만 헐크 스매시 옵션을 사용합니다. prod에서는 항상 문제를 해결하기 위해 새 마이그레이션을 만듭니다. 데이터베이스를 다운 그레이드하는 경우 수동 개입이 필요하기 때문입니다. 나는 자극에 수동 개입이 필요한 것을 좋아하지 않는다.
사랑하지 않음

1
HULK SMASH !!!! --- 멋지게 시도했지만 EF가 재생되지 않았습니다-마지막으로 알려진 것으로 되돌 렸습니다-(마이그레이션 파일 백업) 삭제, 마이그레이션 추가-강제-이전으로 이름이 변경되고 코드가 복사되었습니다. 두 번째 마이그레이션과 같은 방식으로-오류 없음-다시 정상으로
Traci

127

질문에서 알 수 있듯이 이것은 아직 릴리스되지 않은 개발 유형 환경의 마이그레이션에 적용됩니다.

이 문제는 다음 단계로 해결할 수 있습니다. 데이터베이스를 마지막으로 올바른 마이그레이션으로 복원하고 Entity Framework 프로젝트에서 잘못된 마이그레이션을 삭제하고 새 마이그레이션을 생성하여 데이터베이스에 적용하십시오. 참고 : 주석에서 판단 할 때 EF Core를 사용하는 경우 이러한 정확한 명령을 더 이상 적용 할 수 없습니다.

1 단계 : 이전 마이그레이션으로 복원

아직 마이그레이션을 적용하지 않은 경우이 부분을 건너 뛸 수 있습니다. 데이터베이스 스키마를 이전 시점으로 복원하려면 -TargetMigration 옵션과 함께 Update-Database 명령을 실행하여 마지막으로 올바른 마이그레이션을 지정하십시오. 엔티티 프레임 워크 코드가 솔루션의 다른 프로젝트에있는 경우 '-Project'옵션을 사용하거나 패키지 관리자 콘솔에서 기본 프로젝트를 전환해야합니다.

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-migrationEntity Framework 버전에서 명령을 사용할 수없는 경우 원하지 않는 마이그레이션 파일 인 EF 프로젝트 '마이그레이션'폴더를 수동으로 삭제하십시오. 이제 새 이주를 작성하여 데이터베이스에 적용 할 수 있습니다.

3 단계 : 새 마이그레이션 추가

add-migration my_new_migration

4 단계 : 데이터베이스에 마이그레이션 적용

update-database

6
EF Core를 사용하면 Get-Migrations가 제거 된 것 같습니다.
Kevin Burton

1
2 단계 ! -매우 유용한 기능입니다. @KevinBurton이 언급했듯이. 그리고 add-migration "new migration",update-database
알렉산더 프롤로 프

2
업데이트 데이터베이스 – 마이그레이션 : "<마이그레이션이 이전에 적용되었습니다" "@David Sopko
Fuat

감사합니다 @AlexanderFrolov 귀하의 의견을 반영하기 위해 솔루션을 업데이트했습니다.
David Sopko

1
2 단계
Rahul

55

ASP.NET Core v1.0.0과 함께 EF Core를 사용하는 사람들에게는 비슷한 문제가 있었고 다음 명령을 사용하여 문제를 해결했습니다 (@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 개만 있음) 더미 프로젝트에서 단계를 테스트하는 것이 좋습니다.

현재 EF Core (v1.0.0)에 Get-Migrations 명령이없는 것 같으므로 마이그레이션 폴더를보고 수행 한 작업에 익숙해야합니다. 그러나 멋진 도움말 명령이 있습니다.

PM> get-help entityframework

VS2015 SQL Server 개체 탐색기에서 dastabase를 새로 고치면 모든 데이터가 유지되고 되돌리려는 마이그레이션이 사라졌습니다. :)

처음에는 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
업데이트-데이터베이스 -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의 경우 개발에서 많은 비계를 재배치하는 경우 하나의 라이너가 있습니다. 바를 업데이트 한 다음 패키지 관리자 콘솔에서 위쪽 화살표를 계속 사용하여 헹구고 반복하십시오.

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

왜 이것이 필요한가요? 어떤 EF6 버전이 적용되는지 확실하지 않지만 새 마이그레이션 대상이 이미 적용된 경우 Add-Migration에서 '-Force'를 사용하여 다시 스캐 폴딩하면 실제로 다시 스캐 폴딩되지 않고 대신 새 파일을 만듭니다 (이것은 좋습니다) '다운'을 잃고 싶지 않기 때문에). 위의 스 니펫은 필요한 경우 먼저 'Down'을 수행 한 다음 -Force가 다시 스캐 폴딩되도록 올바르게 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.