다음을 통해 공유


자동 Code First 마이그레이션

자동 마이그레이션을 사용하면 각 변경 내용에 대한 코드 파일이 프로젝트에 없는 경우 Code First 마이그레이션 사용할 수 있습니다. 모든 변경 내용을 자동으로 적용할 수 있는 것은 아닙니다. 예를 들어 열 이름 바꾸기를 사용하려면 코드 기반 마이그레이션을 사용해야 합니다.

참고 항목

이 문서에서는 기본 시나리오에서 Code First 마이그레이션을 사용하는 방법을 알고 있다고 가정합니다. 그렇지 않으면 계속하기 전에 Code First 마이그레이션을 읽어야 합니다.

팀 환경에 대한 권장 사항

자동 및 코드 기반 마이그레이션을 섞어서 사용할 수 있지만 이는 팀 개발 시나리오에 권장되지 않습니다. 소스 제어를 사용하는 개발자 팀의 일원인 경우 순수하게 자동 마이그레이션을 사용하거나 순전히 코드 기반 마이그레이션을 사용해야 합니다. 자동 마이그레이션의 제한 사항을 감안할 때 팀 환경에서는 코드 기반 마이그레이션을 사용하는 것이 좋습니다.

초기 모델 및 데이터베이스 만들기

마이그레이션 사용을 시작하기 전에 먼저 사용할 프로젝트와 Code First 모델이 필요합니다. 이 연습에서는 정식 BlogPost 모델을 사용하려고 합니다.

  • MigrationsAutomaticDemo 콘솔 애플리케이션 만들기
  • 최신 버전의 EntityFramework NuGet 패키지를 프로젝트에 추가합니다.
    • 도구 –> 라이브러리 패키지 관리자 –> 패키지 관리자 콘솔
    • Install-Package EntityFramework 명령 실행
  • 아래 표시된 코드가 있는 Model.cs 파일을 추가합니다. 이 코드에서는 도메인 모델을 구성하는 단일 Blog 클래스와 EF Code First 컨텍스트인 BlogContext 클래스를 정의합니다
    using System.Data.Entity;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.Infrastructure;

    namespace MigrationsAutomaticDemo
    {
        public class BlogContext : DbContext
        {
            public DbSet<Blog> Blogs { get; set; }
        }

        public class Blog
        {
            public int BlogId { get; set; }
            public string Name { get; set; }
        }
    }
  • 이제 모델이 준비되었으므로 데이터 액세스를 수행하는 데 사용할 시간입니다. Program.cs 파일을 아래 표시된 코드로 업데이트합니다.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MigrationsAutomaticDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db = new BlogContext())
                {
                    db.Blogs.Add(new Blog { Name = "Another Blog " });
                    db.SaveChanges();

                    foreach (var blog in db.Blogs)
                    {
                        Console.WriteLine(blog.Name);
                    }
                }

                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
  • 애플리케이션을 실행하면 MigrationsAutomaticCodeDemo.BlogContext 데이터베이스가 만들어졌음을 알 수 있습니다.

    데이터베이스 LocalDB

마이그레이션을 사용하도록 설정

이제 모델을 약간 변경할 시간입니다.

  • Blog 클래스에 Url 속성을 소개해 보겠습니다.
    public string Url { get; set; }

애플리케이션을 다시 실행하는 경우 InvalidOperationException이 발생합니다. 이 예외에서는 'BlogContext' 컨텍스트를 지원하는 모델이 변경되었습니다. Code First 마이그레이션을 사용하여 데이터베이스를 업데이트하는 것이 좋습니다.’라고 나타냅니다( http://go.microsoft.com/fwlink/?LinkId=238269).

예외에서 암시하듯이 이제 Code First 마이그레이션 사용을 시작할 시간입니다. 자동 마이그레이션을 사용하고자 하므로 –EnableAutomaticMigrations 스위치를 지정합니다.

  • 패키지 관리자 콘솔에서 Enable-Migrations –EnableAutomaticMigrations 명령을 실행합니다. 이 명령은 프로젝트에 Migrations 폴더를 추가했습니다. 이 새 폴더에는 다음의 파일이 하나 포함되어 있습니다.

  • Configuration 클래스입니다. 이 클래스를 사용하면 컨텍스트에 맞게 마이그레이션이 작동하는 방식을 구성할 수 있습니다. 이 연습에서는 기본 구성만 사용하겠습니다. 프로젝트에는 Code First 컨텍스트가 하나만 있으므로 Enable-Migrations는 이 구성이 적용되는 컨텍스트 유형을 자동으로 채웁니다.

 

첫 번째 자동 마이그레이션

Code First 마이그레이션에는 익숙해져야 하는 다음 두 가지 기본 명령이 있습니다.

  • Add-Migration은 마지막 마이그레이션을 만든 후에 대한 변경 내용에 따라 다음 마이그레이션을 스캐폴드합니다
  • Update-Database는 보류 중인 모든 마이그레이션을 데이터베이스에 적용합니다.

Add-Migration을 사용하지 않고(실제로 필요하지 않은 경우) Code First 마이그레이션이 변경 내용을 자동으로 계산하고 적용하도록 하는 데 집중합니다. Update-Database를 사용하여 Code First 마이그레이션을 가져와 변경 내용(새 Blog.Url 속성)을 데이터베이스에 푸시해 보겠습니다.

  • 패키지 관리자 콘솔에서 Update-Database 명령을 실행합니다.

이제 MigrationsAutomaticDemo.BlogContext 데이터베이스가 업데이트되어 Blogs 테이블에 Url 열이 포함되었습니다.

 

두 번째 자동 마이그레이션

또 다른 변경을 수행하고 Code First 마이그레이션이 자동으로 변경 내용을 데이터베이스에 푸시하도록 하겠습니다.

  • Post 클래스도 추가하겠습니다.
    public class Post
    {
        public int PostId { get; set; }
        [MaxLength(200)]
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
  • 또한 Blog 클래스에 Posts 컬렉션도 추가하여 BlogPost 간 관계의 다른 끝 부분을 만듭니다.
    public virtual List<Post> Posts { get; set; }

이제 Update-Database를 사용하여 데이터베이스를 최신 상태로 유지합니다. 이번에는 Code First 마이그레이션이 실행되는 SQL을 확인할 수 있도록 -Verbose 플래그를 지정하겠습니다.

  • 패키지 관리자 콘솔에서 Update-Database -Verbose 명령을 실행합니다.

코드 기반 마이그레이션 추가

이제 코드 기반 마이그레이션을 사용할 수 있는 항목을 살펴보겠습니다.

  • Blog 클래스에 Rating 속성을 추가해 보겠습니다.
    public int Rating { get; set; }

Update-Database를 실행하여 이러한 변경 내용을 데이터베이스에 푸시할 수 있습니다. 그러나 우리는 null을 허용하지 않는 Blogs.Rating 열을 추가합니다. 테이블에 기존 데이터가 있는 경우 새 열에 대한 데이터 형식의 CLR 기본값이 할당됩니다(등급은 정수이므로 0이됨). 그러나 Blogs 테이블의 기존 행이 적절한 등급으로 시작되도록 기본값인 3을 지정하려고 합니다. Add-Migration 명령을 사용하여 이 변경 내용을 편집할 수 있도록 코드 기반 마이그레이션에 기록해 보겠습니다. Add-Migration 명령을 사용하면 이러한 마이그레이션에 이름을 지정할 수 있습니다. 여기서는 AddBlogRating으로 지정하겠습니다.

  • 패키지 관리자 콘솔에서 Add-Migration AddBlogRating 명령을 실행합니다.
  • 이제 Migrations 폴더에 새 AddBlogRating 마이그레이션이 있습니다. 마이그레이션 파일 이름은 순서를 지정하는 데 도움이 되는 타임스탬프로 미리 확정됩니다. 생성된 코드를 편집하여 Blog.Rating의 기본값인 3을 지정해 보겠습니다(아래 코드의 줄 10).

마이그레이션에는 일부 메타데이터를 캡처하는 코드 숨김 파일도 있습니다. 이 메타데이터를 사용하면 Code First 마이그레이션이 이 코드 기반 마이그레이션 전에 수행한 자동 마이그레이션을 복제할 수 있습니다. 이는 다른 개발자가 마이그레이션을 실행하려는 경우 또는 애플리케이션을 배포하는 경우에 중요합니다.

    namespace MigrationsAutomaticDemo.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;

        public partial class AddBlogRating : DbMigration
        {
            public override void Up()
            {
                AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
            }

            public override void Down()
            {
                DropColumn("Blogs", "Rating");
            }
        }
    }

편집한 마이그레이션이 좋아 보이므로 Update-Database를 사용하여 데이터베이스를 최신 상태로 만들겠습니다.

  • 패키지 관리자 콘솔에서 Update-Database 명령을 실행합니다.

자동 마이그레이션으로 돌아가기

이제 더 간단한 변경을 위해 자동 마이그레이션으로 다시 전환할 수 있습니다. Code First 마이그레이션은 각 코드 기반 마이그레이션에 대해 코드 숨김 파일에 저장하는 메타데이터에 따라 올바른 순서로 자동 및 코드 기반 마이그레이션을 수행합니다.

  • Post.Abstract 속성을 모델에 추가하겠습니다.
    public string Abstract { get; set; }

이제 Update-Database를 사용하여 자동 마이그레이션을 통해 이 변경 사항을 데이터베이스에 푸시하는 Code First 마이그레이션을 가져올 수 있습니다.

  • 패키지 관리자 콘솔에서 Update-Database 명령을 실행합니다.

요약

이 연습에서는 자동 마이그레이션을 사용하여 모델 변경 내용을 데이터베이스에 푸시하는 방법을 알아보았습니다. 또한 더 많은 제어가 필요할 때 자동 마이그레이션 간에 코드 기반 마이그레이션을 스캐폴드하고 실행하는 방법도 알아보았습니다.