참고 항목
EF4.3 이상만 - 이 페이지에서 다루는 기능, API 등은 Entity Framework 4.1에 도입되었습니다. 이전 버전을 사용하는 경우 이 정보의 일부 또는 전체가 적용되지 않습니다.
이 문서에서는 Entity Framework에서 만들지 않은 기존 데이터베이스와 함께 Code First 마이그레이션을 사용하는 방법에 대해 설명합니다.
참고 항목
이 문서에서는 기본 시나리오에서 Code First 마이그레이션을 사용하는 방법을 알고 있다고 가정합니다. 그렇지 않으면 계속하기 전에 Code First 마이그레이션을 읽어야 합니다.
1단계: 모델 만들기
첫 번째 단계는 기존 데이터베이스를 대상으로 하는 Code First 모델을 만드는 것입니다. 기존 데이터베이스에 대한 Code First 항목에서는 이 작업을 수행하는 방법에 대한 자세한 지침을 제공합니다.
참고 항목
데이터베이스 스키마를 변경해야 하는 모델을 변경하기 전에 이 항목의 나머지 단계를 따르는 것이 중요합니다. 다음 단계에서는 모델이 데이터베이스 스키마와 동기화되어야 합니다.
2단계: 마이그레이션 사용
다음 단계에서는 마이그레이션을 사용하도록 설정합니다. 이 작업은 패키지 관리자 콘솔에서 Enable-Migrations 명령을 실행하여 수행할 수 있습니다.
이 명령은 마이그레이션이라는 솔루션에 폴더를 만들고 Configuration이라는 단일 클래스를 내부에 배치합니다. Configuration 클래스는 애플리케이션에 대한 마이그레이션을 구성하는 위치이며, 이에 대한 자세한 내용은 Code First 마이그레이션 항목에서 확인할 수 있습니다.
3단계: 초기 마이그레이션 추가
마이그레이션이 만들어지고 로컬 데이터베이스에 적용되면 이러한 변경 내용을 다른 데이터베이스에도 적용할 수 있습니다. 예를 들어 로컬 데이터베이스는 테스트 데이터베이스일 수 있으며 궁극적으로 프로덕션 데이터베이스 및/또는 다른 개발자 테스트 데이터베이스에도 변경 내용을 적용할 수 있습니다. 이 단계에는 두 가지 옵션이 있으며 다른 데이터베이스의 스키마가 비어 있는지 또는 현재 로컬 데이터베이스의 스키마와 일치하는지 여부에 따라 선택해야 합니다.
- 옵션 1: 기존 스키마를 시작점으로 사용합니다. 나중에 마이그레이션이 적용될 다른 데이터베이스에 현재 있는 로컬 데이터베이스와 동일한 스키마가 있는 경우 이 방법을 사용해야 합니다. 예를 들어 로컬 테스트 데이터베이스가 현재 프로덕션 데이터베이스의 v1과 일치하고 나중에 이러한 마이그레이션을 적용하여 프로덕션 데이터베이스를 v2로 업데이트하는 경우 이를 사용할 수 있습니다.
- 옵션 2: 빈 데이터베이스를 시작점으로 사용합니다. 나중에 마이그레이션이 적용될 다른 데이터베이스가 비어 있거나 아직 존재하지 않는 경우 이 방법을 사용해야 합니다. 예를 들어 테스트 데이터베이스를 사용하여 애플리케이션을 개발하기 시작했지만 마이그레이션을 사용하지 않고 나중에 프로덕션 데이터베이스를 처음부터 만들려는 경우 이를 사용할 수 있습니다.
옵션 1: 기존 스키마를 시작점으로 사용
Code First 마이그레이션은 가장 최신 마이그레이션에 저장된 모델의 스냅샷을 사용하여 모델의 변경 내용을 검색합니다(이에 대한 자세한 정보는 팀 환경의 Code First 마이그레이션에서 확인할 수 있음). 데이터베이스에 이미 현재 모델의 스키마가 있다고 가정하므로 현재 모델을 스냅샷으로 포함하는 빈(no-op) 마이그레이션을 생성합니다.
- 패키지 관리자 콘솔에서 Add-Migration InitialCreate –IgnoreChanges 명령을 실행합니다. 그러면 현재 모델을 스냅샷으로 사용하여 빈 마이그레이션이 만들어집니다.
- 패키지 관리자 콘솔에서 Update-Database 명령을 실행합니다. 그러면 데이터베이스에 InitialCreate 마이그레이션이 적용됩니다. 실제 마이그레이션에는 변경 내용이 포함되지 않으므로 이 마이그레이션이 이미 적용되었음을 나타내는 행이 __MigrationsHistory 테이블에 추가됩니다.
옵션 2: 빈 데이터베이스를 시작점으로 사용
이 시나리오에서는 마이그레이션이 로컬 데이터베이스에 이미 있는 테이블을 포함하여 전체 데이터베이스를 처음부터 만들 수 있어야 합니다. 기존 스키마를 만드는 논리를 포함하는 InitialCreate 마이그레이션을 생성합니다. 그런 다음 기존 데이터베이스를 이 마이그레이션이 이미 적용된 것처럼 보이게 합니다.
- 패키지 관리자 콘솔에서 Add-Migration InitialCreate 명령을 실행합니다. 그러면 기존 스키마를 만드는 마이그레이션이 만들어집니다.
- 새로 만든 마이그레이션의 Up 메서드에서 모든 코드를 주석 처리합니다. 그러면 이미 존재하는 모든 테이블 등을 다시 만들지 않고도 로컬 데이터베이스에 마이그레이션을 '적용'할 수 있습니다.
- 패키지 관리자 콘솔에서 Update-Database 명령을 실행합니다. 그러면 데이터베이스에 InitialCreate 마이그레이션이 적용됩니다. 실제 마이그레이션에는 변경 내용이 포함되어 있지 않으므로(일시적으로 주석 처리했기 때문에) 이 마이그레이션이 이미 적용되었음을 나타내는 행이 __MigrationsHistory 테이블에 추가됩니다.
- Up 메서드에서 코드 주석을 제거합니다. 즉, 이 마이그레이션이 향후 데이터베이스에 적용되면 마이그레이션을 통해 로컬 데이터베이스에 이미 존재하는 스키마가 만들어집니다.
알아두어야 할 사항
기존 데이터베이스에 대해 마이그레이션을 사용할 때 알아야 할 몇 가지 사항이 있습니다.
기본/계산된 이름이 기존 스키마와 일치하지 않을 수 있습니다.
마이그레이션은 마이그레이션을 스캐폴드할 때 열 및 테이블의 이름을 명시적으로 지정합니다. 그러나 마이그레이션을 적용할 때 마이그레이션에서 기본 이름을 계산하는 다른 데이터베이스 개체가 있습니다. 여기에는 인덱스 및 외래 키 제약 조건이 포함됩니다. 기존 스키마를 대상으로 하는 경우 이러한 계산된 이름이 데이터베이스에 실제로 존재하는 이름과 일치하지 않을 수 있습니다.
다음은 이러한 사실을 알고 있어야 하는 경우의 몇 가지 예입니다.
3단계에서 '옵션 1: 기존 스키마를 시작점으로 사용'을 사용한 경우:
- 모델의 향후 변경 내용에 따라 이름이 다른 데이터베이스 개체 중 하나를 변경하거나 삭제해야 하는 경우 스캐폴드된 마이그레이션을 수정하여 올바른 이름을 지정해야 합니다. 마이그레이션 API에는 이 작업을 수행할 수 있는 선택적 Name 매개 변수가 있습니다. 예를 들어 기존 스키마에는 IndexFk_BlogId라는 인덱스가 있는 BlogId 외래 키 열이 포함된 Post 테이블이 있을 수 있습니다. 그러나 기본적으로 마이그레이션에서는 이 인덱스의 이름이 IX_BlogId로 지정되어야 합니다. 이 인덱스를 삭제하는 모델을 변경하는 경우 스캐폴드된 DropIndex 호출을 수정하여 IndexFk_BlogId 이름을 지정해야 합니다.
3단계에서 '옵션 2: 빈 데이터베이스를 시작점으로 사용'을 사용한 경우:
- 마이그레이션에서 잘못된 이름을 사용하여 인덱스 및 외래 키 제약 조건을 삭제하고자 하므로 로컬 데이터베이스에 대해 초기 마이그레이션의 Down 메서드(즉, 빈 데이터베이스로 되돌리기)를 실행하려고 하면 실패할 수 있습니다. 이는 초기 마이그레이션의 Up 메서드를 사용하여 다른 데이터베이스가 처음부터 만들어지기 때문에 로컬 데이터베이스에만 영향을 미칩니다. 기존 로컬 데이터베이스를 빈 상태로 다운그레이드하려는 경우 데이터베이스를 삭제하거나 모든 테이블을 삭제하여 수동으로 수행하는 것이 가장 쉽습니다. 이 초기 다운그레이드 후에는 모든 데이터베이스 개체가 기본 이름으로 다시 만들어지므로 이러한 문제가 다시 나타나지 않습니다.
- 모델의 향후 변경 내용에 따라 이름이 다른 데이터베이스 개체 중 하나를 변경하거나 삭제해야 하는 경우 이름이 기본값과 일치하지 않으므로 이는 기존 로컬 데이터베이스에서 작동하지 않습니다. 그러나 이는 마이그레이션에서 선택한 기본 이름을 사용하므로 '처음부터' 만든 데이터베이스에 대해 작동합니다. 로컬 기존 데이터베이스에서 이러한 변경을 수동으로 수행하거나 마이그레이션을 통해 데이터베이스를 처음부터 다시 만드는 것이 좋습니다( 다른 컴퓨터에서와 같이).
- 초기 마이그레이션의 Up 메서드를 사용하여 만든 데이터베이스는 인덱스 및 외래 키 제약 조건에 대해 계산된 기본 이름이 사용되므로 로컬 데이터베이스와 약간 다를 수 있습니다. 마이그레이션은 기본적으로 외래 키 열에 인덱스를 생성하기 때문에 추가 인덱스로 끝날 수도 있으며, 이는 원래 로컬 데이터베이스에서는 그렇지 않았을 수 있습니다.
모든 데이터베이스 개체가 모델에 표시되는 것은 아닙니다.
모델의 일부가 아닌 데이터베이스 개체는 마이그레이션에서 처리되지 않습니다. 여기에는 보기, 저장 프로시저, 권한, 모델의 일부가 아닌 테이블, 추가 인덱스 등이 포함될 수 있습니다.
다음은 이러한 사실을 알고 있어야 하는 경우의 몇 가지 예입니다.
- '3단계'에서 선택한 옵션에 관계없이 향후 모델 변경 시 이러한 추가 개체를 변경하거나 삭제해야 하는 경우 마이그레이션은 이러한 변경을 알 수 없습니다. 예를 들어 추가 인덱스가 있는 열을 삭제하면 마이그레이션에서 인덱스를 삭제할지 알 수 없습니다. 이를 스캐폴드된 마이그레이션에 수동으로 추가해야 합니다.
- '옵션 2: 빈 데이터베이스를 시작점으로 사용'을 사용한 경우 초기 마이그레이션의 Up 메서드에서 이러한 추가 개체를 만들지 않습니다. 원하는 경우 Up 및 Down 메서드를 수정하여 이러한 추가 개체를 처리할 수 있습니다. 보기와 같이 마이그레이션 API에서 기본적으로 지원되지 않는 개체의 경우 Sql 메서드를 사용하여 원시 SQL을 실행하여 만들거나 삭제할 수 있습니다.
.NET