마이그레이션 관리
모델이 변경되면 마이그레이션이 일반 개발의 일부로 추가 및 제거되고 마이그레이션 파일이 프로젝트의 소스 제어에 체크 인됩니다. 마이그레이션을 관리하려면 먼저 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를 통해 열 이름을 변경할 수 있지만 대부분의 경우 불가능합니다. 예를 들어 기존 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는 마이그레이션을 적용할 때 자체 트랜잭션에서 각 마이그레이션을 자동으로 래핑합니다. 아쉽게도 일부 마이그레이션 작업은 일부 데이터베이스의 트랜잭션 내에서 수행할 수 없습니다. 이러한 경우 migrationBuilder.Sql
suppressTransaction: 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()
사용하여 프로그래밍 방식으로 이 검사를 수행할 수도 있습니다. 마이그레이션을 추가하는 것을 잊어버린 경우 실패하는 단위 테스트를 작성하는 데 사용할 수 있습니다.
모든 마이그레이션 다시 설정
일부 극단적인 경우 모든 마이그레이션을 제거하고 다시 시작해야 할 수 있습니다. 이 작업은 마이그레이션 폴더를 삭제하고 데이터베이스를 삭제하여 쉽게 수행할 수 있습니다. 이 시점에서 전체 현재 스키마를 포함하는 새 초기 마이그레이션을 만들 수 있습니다.
또한 데이터를 잃지 않고 모든 마이그레이션을 재설정하고 단일 마이그레이션을 만들 수도 있습니다. 이를 "스쿼싱"이라고도 하며, 수동으로 해야 하는 작업이 포함됩니다.
- 문제가 발생하는 경우 데이터베이스를 백업합니다.
- 데이터베이스에서 마이그레이션 기록 테이블(예: SQL Server의
DELETE FROM [__EFMigrationsHistory]
)에서 모든 행을 삭제합니다. - 마이그레이션 폴더를 삭제합니다.
- 새 마이그레이션을 만들고 해당 마이그레이션에 대한 SQL 스크립트를 생성합니다(
dotnet ef migrations script
). - 테이블이 이미 있으므로 마이그레이션 기록에 단일 행을 삽입하여 첫 번째 마이그레이션이 이미 적용되었음을 기록합니다. SQL 삽입은 위에서 생성된 SQL 스크립트의 마지막 작업이며 다음과 유사합니다(값을 업데이트하는 것을 잊지 마세요).
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');
경고
마이그레이션 폴더가 삭제되면 사용자 지정 마이그레이션 코드 손실됩니다. 유지하려면 모든 사용자 지정을 새 초기 마이그레이션에 수동으로 적용해야 합니다.
추가 리소스
- Entity Framework Core 도구 참조 - .NET Core CLI: 업데이트, 삭제, 추가, 제거 등의 명령을 포함합니다.
- Entity Framework Core 도구 참조 - Visual Studio 패키지 관리자 콘솔 : 업데이트, 삭제, 추가, 제거 등의 명령을 포함합니다.
.NET