마이그레이션 관리
모델이 변경되면 마이그레이션이 일반 개발의 일부로 추가 및 제거되고 마이그레이션 파일이 프로젝트의 소스 제어에 체크 인됩니다. 마이그레이션을 관리하려면 먼저 EF Core 명령줄 도구를 설치해야 합니다.
팁
DbContext
가 시작 프로젝트와 다른 어셈블리에 있는 경우 패키지 관리자 콘솔 도구 또는 .NET Core CLI 도구에서 대상 및 시작 프로젝트를 명시적으로 지정할 수 있습니다.
마이그레이션 추가
모델이 변경된 후 해당 변경에 대한 마이그레이션을 추가할 수 있습니다.
dotnet ef migrations add AddBlogCreatedTimestamp
마이그레이션 이름은 버전 제어 시스템의 커밋 메시지처럼 사용할 수 있습니다. 예를 들어 변경 내용이 Blog
엔터티의 새 CreatedTimestamp
속성인 경우 AddBlogCreatedTimestamp와 같은 이름을 선택할 수 있습니다.
프로젝트의 Migrations 디렉터리 아래 3개 파일이 추가됩니다.
- XXXXXXXXXXXXXX_AddCreatedTimestamp.cs -- 주 마이그레이션 파일입니다. 마이그레이션을 적용하고(
Up
) 변환하는 데(Down
) 필요한 작업을 포함합니다. - XXXXXXXXXXXXXX_AddCreatedTimestamp.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는 일반적으로 열을 삭제하고 새 열(두 개의 별도 변경 내용)을 만드는 시기와 열 이름을 바꿔야 하는 시기를 알 수 없습니다. 위의 마이그레이션이 있는 그대로 적용되면 모든 고객 이름이 손실됩니다. 열의 이름을 바꾸려면 위에서 생성된 마이그레이션을 다음으로 바꿉니다.
migrationBuilder.RenameColumn(
name: "Name",
table: "Customers",
newName: "FullName");
팁
작업으로 인해 데이터가 손실될 수 있는 경우(예: 열 삭제) 마이그레이션 스캐폴딩 프로세스가 경고를 표시합니다. 해당 경고가 표시되면 특히 마이그레이션 코드가 정확한지 검토해야 합니다.
원시 SQL 추가
기본 제공 API를 통해 열 이름을 변경할 수 있지만 대부분의 경우 불가능합니다. 예를 들어 기존 FirstName
및 LastName
속성을 새 단일 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는 마이그레이션을 적용할 때 자체 트랜잭션에서 각 마이그레이션을 자동으로 래핑합니다. 아쉽게도 일부 마이그레이션 작업은 일부 데이터베이스의 트랜잭션 내에서 수행할 수 없습니다. 이러한 경우 suppressTransaction: true
을 migrationBuilder.Sql
에 전달하여 트랜잭션에서 옵트아웃할 수 있습니다.
마이그레이션 제거
때때로 마이그레이션을 추가하고 적용하기 전에 EF Core 모델에 추가적인 변경이 필요한 경우가 있습니다. 마지막 마이그레이션을 제거하려면다음 명령을 사용합니다.
dotnet ef migrations remove
마이그레이션을 제거한 후 추가적인 모델 변경을 수행하고 다시 추가합니다.
Warning
프로덕션 데이터베이스에 이미 적용된 마이그레이션을 제거하지 마세요. 이렇게 하면 이러한 마이그레이션을 데이터베이스에서 되돌릴 수 없으며 후속 마이그레이션으로 인한 가정이 중단될 수 있습니다.
마이그레이션 나열
다음과 같이 모든 기존 마이그레이션을 나열할 수 있습니다.
dotnet ef migrations list
보류 중인 모델 변경 내용 확인
참고 항목
이 기능은 EF Core 8.0에서 추가되었습니다.
경우에 따라 마지막 마이그레이션 이후 모델 변경 내용이 있는지 확인할 수 있습니다. 이를 통해 사용자 또는 팀원이 마이그레이션을 추가하는 것을 잊은 경우를 알 수 있습니다. 이 작업을 수행하는 한 가지 방법은 이 명령을 사용하는 것입니다.
dotnet ef migrations has-pending-model-changes
context.Database.HasPendingModelChanges()
를 사용하여 프로그래밍 방식으로 확인할 수도 있습니다. 마이그레이션을 추가하는 것을 잊어버린 경우 실패하는 단위 테스트를 작성하는 데 사용할 수 있습니다.
모든 마이그레이션 다시 설정
일부 극단적인 경우 모든 마이그레이션을 제거하고 다시 시작해야 할 수 있습니다. 이 작업은 마이그레이션 폴더를 삭제하고 데이터베이스를 삭제하여 쉽게 수행할 수 있습니다. 이 시점에서 전체 현재 스키마를 포함하는 새 초기 마이그레이션을 만들 수 있습니다.
또한 데이터를 잃지 않고 모든 마이그레이션을 재설정하고 단일 마이그레이션을 만들 수도 있습니다. 이를 "squashing"이라고도 하며 몇 가지 수동 작업이 포함됩니다.
- 문제가 발생하는 경우 데이터베이스를 백업합니다.
- 데이터베이스의 마이그레이션 기록 테이블에서 모든 행을 삭제합니다.(예: SQL Server의
DELETE FROM [__EFMigrationsHistory]
) - 마이그레이션 폴더를 삭제합니다.
- 새 마이그레이션을 만들고
dotnet ef migrations script
를 위한 SQL 스크립트를 생성합니다. - 테이블이 이미 있으므로 마이그레이션 기록에 단일 행을 삽입하여 첫 번째 마이그레이션이 이미 적용되었음을 기록합니다. SQL 삽입은 위에서 생성된 SQL 스크립트의 마지막 작업이며 다음과 유사합니다(값을 업데이트하는 것을 잊지 마세요).
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');
Warning
마이그레이션 폴더가 삭제되면 사용자 지정 마이그레이션 코드가 손실됩니다. 유지하려면 모든 사용자 지정을 새 초기 마이그레이션에 수동으로 적용해야 합니다.
추가 리소스
- Entity Framework Core 도구 참조 - .NET Core CLI: 업데이트, 드롭, 추가, 제거 등의 명령을 포함합니다.
- Entity Framework Core 도구 참조 - Visual Studio의 패키지 관리자 콘솔: 업데이트, 드롭, 추가, 제거 등의 명령을 포함합니다.
.NET