마이그레이션 적용

마이그레이션이 추가되면 배포하고 데이터베이스에 적용해야 합니다. 이 작업을 수행하기 위한 다양한 전략이 있으며, 일부는 프로덕션 환경에 더 적합하고 다른 일부는 개발 수명 주기에 적합합니다.

참고

배포 전략이 무엇이든 프로덕션 데이터베이스에 적용하기 전에 항상 생성된 마이그레이션을 검사하고 테스트합니다. 마이그레이션은 의도 이름을 바꿀 때 열을 삭제하거나 데이터베이스에 적용할 때 여러 가지 이유로 실패할 수 있습니다.

SQL 스크립트

프로덕션 데이터베이스에 마이그레이션을 배포하는 권장 방법은 SQL 스크립트를 생성하는 것입니다. 이 전략의 장점은 다음과 같습니다.

  • SQL 스크립트는 정확도를 검토할 수 있습니다. 이는 프로덕션 데이터베이스에 스키마 변경 내용을 적용하는 것이 데이터 손실을 수반할 수 있는 잠재적으로 위험한 작업이므로 중요합니다.
  • 경우에 따라 프로덕션 데이터베이스의 특정 요구 사항에 맞게 스크립트를 튜닝할 수 있습니다.
  • SQL 스크립트는 배포 기술과 함께 사용할 수 있으며 CI 프로세스의 일부로 생성될 수도 있습니다.
  • SQL 스크립트는 DBA에 제공될 수 있으며 별도로 관리 및 보관할 수 있습니다.

기본 사용

다음은 빈 데이터베이스에서 최신 마이그레이션으로 SQL 스크립트를 생성합니다.

dotnet ef migrations script

From을 사용할 경우(implied에 대해)

다음은 지정된 마이그레이션에서 최신 마이그레이션으로의 SQL 스크립트를 생성합니다.

dotnet ef migrations script AddNewTables

From 및 To를 사용할 경우

다음은 지정된 마이그레이션에서 지정된 from 마이그레이션으로의 SQL 스크립트를 to 생성합니다.

dotnet ef migrations script AddNewTables AddAuditTable

롤백 스크립트를 생성하기 위해 to보다 최신인 from을 사용할 수 있습니다.

경고

‘잠재적 데이터 손실 시나리오를 기록해 두세요.’

스크립트 생성은 생성해야 하는 마이그레이션 범위를 나타내는 다음 두 인수를 허용합니다.

  • from 마이그레이션은 스크립트를 실행하기 전에 데이터베이스에 적용된 마지막 마이그레이션이 되어야 합니다. 적용된 마이그레이션이 없으면 0(기본값)을 지정합니다.
  • to 마이그레이션을 스크립트를 실행한 후에 데이터베이스에 적용된 마지막 마이그레이션이 되어야 합니다. 기본값은 프로젝트의 마지막 마이그레이션입니다.

Idempotent SQL 스크립트

위에서 생성된 SQL 스크립트는 한 마이그레이션에서 다른 마이그레이션으로 스키마를 변경하기 위해만 적용할 수 있습니다. 스크립트를 적절하게 적용하고 올바른 마이그레이션 상태의 데이터베이스에만 적용해야 합니다. 또한 EF Core는 마이그레이션 기록 테이블을 통해 이미 적용된 마이그레이션을 내부적으로 확인하고 누락된 마이그레이션만 적용하는 멱등원 스크립트 생성을 지원합니다. 이 기능은 데이터베이스에 마지막으로 적용된 마이그레이션이 무엇인지 정확히 알지 못하거나 각각 다른 마이그레이션에 있을 수 있는 여러 데이터베이스에 배포하는 경우에 유용합니다.

다음은 idempotent 마이그레이션을 생성합니다.

dotnet ef migrations script --idempotent

명령줄 도구

EF 명령줄 도구를 사용하여 데이터베이스에 마이그레이션을 적용할 수 있습니다. 로컬 개발 및 마이그레이션 테스트를 위해 생산적이지만 이 방법은 프로덕션 데이터베이스를 관리하는 데 적합하지 않습니다.

  • SQL 명령은 개발자에게 검사하거나 수정할 기회를 주지 않고 도구에서 직접 적용됩니다. 프로덕션 환경에서는 위험할 수 있습니다.
  • .NET SDK 및 EF 도구는 프로덕션 서버에 설치되어야 하며 프로젝트의 소스 코드가 필요합니다.

다음은 데이터베이스를 최신 마이그레이션으로 업데이트합니다.

dotnet ef database update

다음은 지정된 마이그레이션으로 데이터베이스를 업데이트합니다.

dotnet ef database update AddNewTables

이전 마이그레이션으로 롤백하는 데도 사용할 수 있습니다.

경고

‘잠재적 데이터 손실 시나리오를 기록해 두세요.’

명령줄 도구를 통해 마이그레이션을 적용하는 방법에 대한 자세한 내용은 EF Core 도구 참조를 참조하세요.

번들

참고

이 기능은 EF Core 6.0에서 도입되었습니다.

마이그레이션 번들은 데이터베이스에 마이그레이션을 적용하는 데 사용할 수 있는 단일 파일 실행 파일입니다. SQL 스크립트 및 명령줄 도구의 몇 가지 단점을 해결합니다.

  • SQL 스크립트를 실행하려면 추가 도구가 필요합니다.
  • 이러한 도구의 트랜잭션 처리 및 계속 오류 동작은 일관되지 않으며 때로는 예기치 않은 경우가 있습니다. 이렇게 하면 마이그레이션을 적용할 때 오류가 발생하는 경우 데이터베이스가 정의되지 않은 상태로 남을 수 있습니다.
  • 번들은 CI 프로세스의 일부로 생성되고 나중에 배포 프로세스의 일부로 쉽게 실행할 수 있습니다.
  • 번들은 .NET SDK 또는 EF 도구(또는 자체 포함 시 .NET 런타임)를 설치하지 않고도 실행할 수 있으며 프로젝트의 소스 코드가 필요하지 않습니다.

다음은 번들을 생성합니다.

dotnet ef migrations bundle

다음은 Linux용 자체 포함 번들을 생성합니다.

dotnet ef migrations bundle --self-contained -r linux-x64

번들을 만드는 방법에 대한 자세한 내용은 EF Core 도구 참조를 참조하세요.

efbundle

결과 실행 파일의 이름은 기본적으로 지정 efbundle 됩니다. 데이터베이스를 최신 마이그레이션으로 업데이트하는 데 사용할 수 있습니다. 실행 dotnet ef database update 또는 Update-Database.에 해당합니다.

인수:

인수 Description
<MIGRATION> 대상 마이그레이션입니다. '0'이면 모든 마이그레이션이 되돌아갑니다. 기본값은 마지막 마이그레이션입니다.

옵션:

옵션 Short Description
--connection <CONNECTION> 데이터베이스에 대한 연결 문자열입니다. 기본값은 AddDbContext 또는 OnConfiguring에 지정된 항목입니다.
--verbose -v 자세한 정보 출력을 표시합니다.
--no-color 출력에 색을 지정하지 마세요.
--prefix-output 수준이 있는 접두사 출력입니다.

다음 예제에서는 지정된 사용자 이름 및 암호를 사용하여 로컬 SQL Server 인스턴스에 마이그레이션을 적용합니다.

.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password=myPassword'

런타임에 마이그레이션 적용

애플리케이션 자체가 일반적으로 시작하는 동안 프로그래밍 방식으로 마이그레이션을 적용할 수 있습니다. 마이그레이션의 로컬 개발 및 테스트에 생산적이지만 이 방법은 다음과 같은 이유로 프로덕션 데이터베이스를 관리하는 데 적합하지 않습니다.

  • 애플리케이션의 여러 인스턴스가 실행 중인 경우 두 애플리케이션 모두 마이그레이션을 동시에 적용하려고 시도하고 실패(또는 더 나쁜 경우 데이터 손상을 일으킬 수 있음)할 수 있습니다.
  • 마찬가지로 다른 애플리케이션이 데이터베이스를 마이그레이션하는 동안 애플리케이션이 데이터베이스에 액세스하는 경우 심각한 문제가 발생할 수 있습니다.
  • 데이터베이스 스키마를 수정하려면 애플리케이션에 상승된 액세스 권한이 있어야 합니다. 일반적으로 프로덕션 환경에서 애플리케이션의 데이터베이스 권한을 제한하는 것이 좋습니다.
  • 문제가 발생한 경우 적용된 마이그레이션을 롤백할 수 있어야 합니다. 다른 전략은 이를 쉽고 빠르게 제공합니다.
  • SQL 명령은 개발자에게 검사하거나 수정할 기회를 주지 않고 프로그램에서 직접 적용됩니다. 이는 프로덕션 환경에서 위험할 수 있습니다.

프로그래밍 방식으로 마이그레이션을 적용하려면 .를 호출합니다 context.Database.Migrate(). 예를 들어 일반적인 ASP.NET 애플리케이션은 다음을 수행할 수 있습니다.

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        db.Database.Migrate();
    }

    host.Run();
}

Migrate() 고급 시나리오에 사용할 수 있는 서비스를 기반으로 IMigrator 빌드됩니다. myDbContext.GetInfrastructure().GetService<IMigrator>()를 사용하여 액세스합니다.

경고

  • 프로덕션 환경에서 이 방법을 사용하기 전에 신중하게 고려해야 합니다. 경험에 따르면 이 배포 전략의 단순성은 만드는 문제보다 더 큽니다. 대신 마이그레이션에서 SQL 스크립트를 생성하는 것이 좋습니다.
  • Migrate()에 앞서 EnsureCreated()를 호출하지 않습니다. EnsureCreated()는 마이그레이션을 무시하고 스키마를 만들어 Migrate()에 실패합니다.