다음을 통해 공유


마이그레이션 관리

모델이 변경되면 마이그레이션이 일반 개발의 일부로 추가 및 제거되고 마이그레이션 파일이 프로젝트의 소스 제어에 체크 인됩니다. 마이그레이션을 관리하려면 먼저 EF Core 명령줄 도구설치해야 합니다.

팁 (조언)

DbContext 시작 프로젝트와 다른 어셈블리에 있는 경우 패키지 관리자 콘솔 도구 또는 .NET Core CLI 도구대상 및 시작 프로젝트를 명시적으로 지정할 수 있습니다.

마이그레이션 추가

모델이 변경된 후 해당 변경에 대한 마이그레이션을 추가할 수 있습니다.

dotnet ef migrations add AddBlogCreatedTimestamp

마이그레이션 이름은 버전 제어 시스템의 커밋 메시지처럼 사용할 수 있습니다. 예를 들어 변경 내용이 Blog 엔터티의 새 CreatedTimestamp 속성인 경우 AddBlogCreatedTimestamp 같은 이름을 선택할 수 있습니다.

Migrations 디렉터리 아래에 세 개의 파일이 프로젝트에 추가됩니다.

  • XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.cs-- 기본 마이그레이션 파일입니다. 마이그레이션을 적용하고(Up) 되돌리는 데 필요한 작업을 포함합니다(Down).
  • XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.Designer.cs--마이그레이션 메타데이터 파일입니다. EF에서 사용하는 정보를 포함합니다.
  • MyContextModelSnapshot.cs--현재 모델의 스냅샷입니다. 다음 마이그레이션을 추가할 때 변경된 내용을 확인하는 데 사용됩니다.

파일 이름의 타임스탬프를 사용하면 변경 내용의 진행률을 볼 수 있도록 시간순으로 순서를 유지할 수 있습니다.

네임스페이스

자유롭게 마이그레이션 파일을 이동하고 해당 네임스페이스를 수동으로 변경할 수 있습니다. 새 마이그레이션은 마지막 마이그레이션의 형제처럼 만들어집니다. 또는 다음과 같이 생성 시 디렉터리를 지정할 수 있습니다.

dotnet ef migrations add InitialCreate --output-dir Your/Directory

비고

--namespace사용하여 디렉터리와 독립적으로 네임스페이스를 변경할 수도 있습니다.

마이그레이션 코드 사용자 지정

EF Core는 일반적으로 정확한 마이그레이션을 만들지만 항상 코드를 검토하고 원하는 변경 내용에 해당하는지 확인해야 합니다. 경우에 따라 그렇게 해야 할 수도 있습니다.

열 이름 변경

마이그레이션을 사용자 지정해야 하는 한 가지 주목할 만한 예는 속성 이름을 바꾸는 경우입니다. 예를 들어 속성 이름을 Name에서 FullName로 변경하면, EF Core는 다음과 같은 마이그레이션을 생성합니다.

migrationBuilder.DropColumn(
    name: "Name",
    table: "Customers");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customers",
    nullable: true);

EF Core는 일반적으로 열을 삭제하고 새 열을 만드는 경우(두 개의 별도 변경 사항) 및 열 이름을 변경해야 하는 시기를 알 수 없습니다. 위의 마이그레이션이 as-is적용되면 모든 고객 이름이 손실됩니다. 열 이름을 바꾸려면 위에서 생성된 마이그레이션을 다음으로 바꿉니다.

migrationBuilder.RenameColumn(
    name: "Name",
    table: "Customers",
    newName: "FullName");

팁 (조언)

마이그레이션 스캐폴딩 프로세스는 작업으로 인해 데이터가 손실될 수 있는 경우(예: 열 삭제) 경고를 표시합니다. 해당 경고가 표시되면 특히 마이그레이션 코드를 검토하여 정확도를 확인해야 합니다.

원시 SQL 추가

기본 제공 API를 통해 열 이름을 변경할 수 있지만 대부분의 경우 불가능합니다. 예를 들어 기존 FirstNameLastName 속성을 새 FullName 속성으로 바꿀 수 있습니다. EF Core에서 생성된 마이그레이션은 다음과 같습니다.

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

이전과 마찬가지로 원치 않는 데이터 손실이 발생합니다. 이전 열에서 데이터를 전송하기 위해 마이그레이션을 다시 정렬하고 다음과 같이 원시 SQL 작업을 도입합니다.

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

migrationBuilder.Sql(
@"
    UPDATE Customer
    SET FullName = FirstName + ' ' + LastName;
");

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

원시 SQL을 통한 임의 변경

원시 SQL을 사용하여 EF Core에서 인식하지 못하는 데이터베이스 개체를 관리할 수도 있습니다. 이렇게 하려면 모델을 변경하지 않고 마이그레이션을 추가합니다. 빈 마이그레이션이 생성되고 원시 SQL 작업으로 채울 수 있습니다.

예를 들어 다음 마이그레이션은 SQL Server 저장 프로시저를 만듭니다.

migrationBuilder.Sql(
@"
    EXEC ('CREATE PROCEDURE getFullName
        @LastName nvarchar(50),
        @FirstName nvarchar(50)
    AS
        RETURN @LastName + @FirstName;')");

팁 (조언)

EXEC 문이 SQL 일괄 처리의 첫 번째 또는 유일한 문이어야 하는 경우에 사용됩니다. 참조된 열이 현재 테이블에 없을 때 발생할 수 있는 idempotent 마이그레이션 스크립트의 파서 오류를 해결하는 데 사용할 수도 있습니다.

다음을 포함하여 데이터베이스의 모든 측면을 관리하는 데 사용할 수 있습니다.

  • 저장된 프로시저
  • 전체 텍스트 검색
  • 기능
  • 발동 조건
  • 조회수

대부분의 경우 EF Core는 마이그레이션을 적용할 때 자체 트랜잭션에서 각 마이그레이션을 자동으로 래핑합니다. 아쉽게도 일부 마이그레이션 작업은 일부 데이터베이스의 트랜잭션 내에서 수행할 수 없습니다. 이러한 경우 migrationBuilder.SqlsuppressTransaction: true 전달하여 트랜잭션을 옵트아웃할 수 있습니다.

마이그레이션 제거

마이그레이션을 추가하고 적용하기 전에 EF Core 모델을 추가로 변경해야 하는 경우가 있습니다. 마지막 마이그레이션을 제거하려면 이 명령을 사용합니다.

dotnet ef migrations remove

마이그레이션을 제거한 후 추가 모델을 변경하고 다시 추가할 수 있습니다.

경고

프로덕션 데이터베이스에 이미 적용된 마이그레이션은 제거하지 마세요. 이렇게 하면 이러한 마이그레이션을 데이터베이스에서 되돌릴 수 없으며 후속 마이그레이션으로 인한 가정이 중단될 수 있습니다.

마이그레이션 목록

다음과 같이 모든 기존 마이그레이션을 나열할 수 있습니다.

dotnet ef migrations list

보류 중인 모델 변경 확인

비고

이 기능은 EF Core 8.0에서 추가되었습니다.

경우에 따라 마지막 마이그레이션 이후 모델 변경 내용이 있는지 확인할 수 있습니다. 이렇게 하면 사용자 또는 팀원이 마이그레이션을 추가하는 것을 잊은 경우를 알 수 있습니다. 이 작업을 수행하는 한 가지 방법은 이 명령을 사용하는 것입니다.

dotnet ef migrations has-pending-model-changes

context.Database.HasPendingModelChanges()사용하여 프로그래밍 방식으로 이 검사를 수행할 수도 있습니다. 마이그레이션을 추가하는 것을 잊어버린 경우 실패하는 단위 테스트를 작성하는 데 사용할 수 있습니다.

모든 마이그레이션 다시 설정

일부 극단적인 경우 모든 마이그레이션을 제거하고 다시 시작해야 할 수 있습니다. 이 작업은 마이그레이션 폴더를 삭제하고 데이터베이스를 삭제하여 쉽게 수행할 수 있습니다. 이 시점에서 전체 현재 스키마를 포함하는 새 초기 마이그레이션을 만들 수 있습니다.

또한 데이터를 잃지 않고 모든 마이그레이션을 재설정하고 단일 마이그레이션을 만들 수도 있습니다. 이를 "스쿼싱"이라고도 하며, 수동으로 해야 하는 작업이 포함됩니다.

  1. 문제가 발생하는 경우 데이터베이스를 백업합니다.
  2. 데이터베이스에서 마이그레이션 기록 테이블(예: SQL Server의 DELETE FROM [__EFMigrationsHistory])에서 모든 행을 삭제합니다.
  3. 마이그레이션 폴더를 삭제합니다.
  4. 새 마이그레이션을 만들고 해당 마이그레이션에 대한 SQL 스크립트를 생성합니다(dotnet ef migrations script).
  5. 테이블이 이미 있으므로 마이그레이션 기록에 단일 행을 삽입하여 첫 번째 마이그레이션이 이미 적용되었음을 기록합니다. SQL 삽입은 위에서 생성된 SQL 스크립트의 마지막 작업이며 다음과 유사합니다(값을 업데이트하는 것을 잊지 마세요).
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');

경고

마이그레이션 폴더가 삭제되면 사용자 지정 마이그레이션 코드 손실됩니다. 유지하려면 모든 사용자 지정을 새 초기 마이그레이션에 수동으로 적용해야 합니다.

추가 리소스