Entity Framework-코드 우선 마이그레이션

Entity Framework 4.3에는 시간이 지남에 따라 모델이 변경됨에 따라 데이터베이스 스키마를 점진적으로 발전시킬 수있는 새로운 Code First 마이그레이션 기능이 포함되어 있습니다. 대부분의 개발자에게 이것은 데이터베이스를 수동으로 업데이트하거나 모델이 변경 될 때이를 삭제하고 다시 만들어야하는 4.1 및 4.2 릴리스의 데이터베이스 이니셜 라이저 옵션에 비해 크게 향상되었습니다.

  • Entity Framework 4.3 이전에는 데이터베이스에 이미 데이터 (시드 데이터 제외) 또는 기존 저장 프로 시저, 트리거 등이있는 경우 이러한 전략이 전체 데이터베이스를 삭제하고 다시 만드는 데 사용되었으므로 데이터 및 기타 DB를 잃게됩니다. 사물.

  • 마이그레이션을 통해 기존 데이터 또는 기타 데이터베이스 개체를 잃지 않고 모델이 변경 될 때 데이터베이스 스키마를 자동으로 업데이트합니다.

  • MigrateDatabaseToLatestVersion이라는 새 데이터베이스 이니셜 라이저를 사용합니다.

마이그레이션에는 두 가지 종류가 있습니다.

  • 자동화 된 마이그레이션
  • 코드 기반 마이그레이션

자동화 된 마이그레이션

자동 마이그레이션은 Entity 프레임 워크 4.3에서 처음 도입되었습니다. 자동 마이그레이션에서는 코드 파일에서 데이터베이스 마이그레이션을 수동으로 처리 할 필요가 없습니다. 예를 들어 각 변경에 대해 도메인 클래스도 변경해야합니다. 그러나 자동화 된 마이그레이션을 사용하려면 패키지 관리자 콘솔에서 명령을 실행하기 만하면됩니다.

자동화 된 마이그레이션의 다음 단계별 프로세스를 살펴 보겠습니다.

Code First 접근 방식을 사용하면 애플리케이션에 사용할 데이터베이스가 없습니다.

이 예에서는 다음 코드에 표시된대로 Student, Course 및 Enrollment와 같은 3 가지 기본 클래스로 시작합니다.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }

}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

다음은 컨텍스트 클래스입니다.

public class MyContext : DbContext {
   public MyContext() : base("MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

애플리케이션을 실행하기 전에 자동 마이그레이션을 활성화해야합니다.

Step 1 − 도구 → NuGet 패키지 관리자 → 패키지 관리자 콘솔에서 패키지 관리자 콘솔을 엽니 다.

Step 2 − 자동 마이그레이션을 활성화하려면 패키지 관리자 콘솔에서 다음 명령을 실행하십시오.

PM> enable-migrations -EnableAutomaticMigrations:$true

Step 3 − 명령이 성공적으로 실행되면 다음 코드와 같이 프로젝트의 Migration 폴더에 내부 봉인 된 구성 클래스를 생성합니다.

namespace EFCodeFirstDemo.Migrations {

   using System;
   using System.Data.Entity;
   using System.Data.Entity.Migrations;
   using System.Linq;
	
   internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDemo.MyContext> {

      public Configuration() {
         AutomaticMigrationsEnabled = true;
         ContextKey = "EFCodeFirstDemo.MyContext";
      }

      protected override void Seed(EFCodeFirstDemo.MyContext context) {

         //  This method will be called after migrating to the latest version.
         //  You can use the DbSet<T>.AddOrUpdate() helper extension method
         //  to avoid creating duplicate seed data. E.g.

         //  context.People.AddOrUpdate(
            //  p ⇒ p.FullName, 
            //  new Person { FullName = "Andrew Peters" }, 
            //  new Person { FullName = "Brice Lambson" }, 
            //  new Person { FullName = "Rowan Miller" }
         //  );
      }
   }
}

Step 4 − 새로운 DB 초기화 전략 MigrateDatabaseToLatestVersion을 사용하여 컨텍스트 클래스에서 데이터베이스 초기화 프로그램을 설정합니다.

public class MyContext : DbContext {

   public MyContext() : base("MyContextDB") {
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, 
         EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }

}

Step 5− 자동 마이그레이션을 설정했습니다. 애플리케이션을 실행하면 모델을 변경할 때 자동으로 마이그레이션을 처리합니다.

Step 6− 보시다시피 하나의 시스템 테이블 __MigrationHistory가 다른 테이블과 함께 데이터베이스에 생성됩니다. __MigrationHistory에서 자동 마이그레이션은 데이터베이스 변경 기록을 유지합니다.

Step 7− 다른 엔티티 클래스를 도메인 클래스로 추가하고 애플리케이션을 실행하면 데이터베이스에 테이블이 생성됩니다. 다음 StudentLogIn 클래스를 추가해 보겠습니다.

public class StudentLogIn {
   [Key, ForeignKey("Student")]
   public int ID { get; set; }
   public string EmailID { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Step 8 − 다음 코드와 같이 컨텍스트 클래스에 위에서 언급 한 클래스에 대한 DBSet을 추가하는 것을 잊지 마십시오.

public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }

Step 9 − 애플리케이션을 다시 실행하면 StudentsLogIn 테이블이 데이터베이스에 추가 된 것을 볼 수 있습니다.

자동화 된 마이그레이션에 대해 언급 한 위 단계는 엔터티에서만 작동합니다. 예를 들어 다른 엔티티 클래스를 추가하거나 기존 엔티티 클래스를 제거하려면 성공적으로 마이그레이션됩니다. 그러나 엔티티 클래스에 속성을 추가하거나 제거하면 예외가 발생합니다.

Step 10 − 속성 마이그레이션을 처리하려면 구성 클래스 생성자에서 AutomaticMigrationDataLossAllowed = true를 설정해야합니다.

public Configuration() {
   AutomaticMigrationsEnabled = true;
   AutomaticMigrationDataLossAllowed = true;
   ContextKey = "EFCodeFirstDemo.MyContext";
}

코드 기반 마이그레이션

새 애플리케이션을 개발할 때 데이터 모델은 자주 변경되며 모델이 변경 될 때마다 데이터베이스와 동기화되지 않습니다. 데이터 모델을 변경할 때마다 데이터베이스를 자동으로 삭제하고 다시 만들도록 Entity Framework를 구성했습니다. 코드 기반 마이그레이션은 마이그레이션에 대한 더 많은 제어를 원할 때 유용합니다.

  • 엔터티 클래스를 추가, 제거 또는 변경하거나 DbContext 클래스를 변경하면 다음에 애플리케이션을 실행할 때 기존 데이터베이스가 자동으로 삭제되고 모델과 일치하는 새 데이터베이스를 만들고 테스트 데이터로 시드합니다.

  • Code First 마이그레이션 기능은 Code First가 데이터베이스를 삭제하고 다시 만드는 대신 데이터베이스 스키마를 업데이트 할 수 있도록하여이 문제를 해결합니다. 애플리케이션을 배포하려면 마이그레이션을 활성화해야합니다.

다음은 데이터베이스의 변경 사항을 마이그레이션하는 기본 규칙입니다.

  • 마이그레이션 활성화
  • 마이그레이션 추가
  • 데이터베이스 업데이트

코드 기반 마이그레이션의 다음 단계별 프로세스를 살펴 보겠습니다.

코드 우선 접근 방식을 사용하면 애플리케이션을위한 데이터베이스가 없습니다.

이 예에서는 다음 코드에 표시된대로 Student, Course 및 Enrollment와 같은 3 가지 기본 클래스로 다시 시작합니다.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }

}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

다음은 컨텍스트 클래스입니다.

public class MyContext : DbContext {

   public MyContext() : base("MyContextDB") {
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<
         MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }

}

Step 1 − 응용 프로그램을 실행하기 전에 마이그레이션을 활성화해야합니다.

Step 2 − 도구 → NuGet 패키지 관리자 → 패키지 관리자 콘솔에서 패키지 관리자 콘솔을 엽니 다.

Step 3 − 마이그레이션이 이미 활성화되어 있습니다. 이제 다음 명령을 실행하여 애플리케이션에 마이그레이션을 추가하십시오.

PM> add-migration "UniDB Schema"

Step 4 − 명령이 성공적으로 실행되면 다음 이미지와 같이 타임 스탬프 접두사를 사용하여 명령에 전달한 매개 변수의 이름으로 마이그레이션 폴더에 새 파일이 생성 된 것을 볼 수 있습니다.

Step 5 − "update-database"명령을 사용하여 데이터베이스를 생성하거나 업데이트 할 수 있습니다.

PM> Update-Database -Verbose

"-Verbose"플래그는 콘솔의 대상 데이터베이스에 적용되는 SQL 문을 표시하도록 지정합니다.

Step 6 − 학생 클래스에 'Age'속성을 하나 더 추가 한 다음 update 문을 실행 해 보겠습니다.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public int Age { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

PM → Update-Database –Verbose를 실행하면 명령이 성공적으로 실행되면 새 열 Age가 데이터베이스에 추가 된 것을 볼 수 있습니다.

더 나은 이해를 위해 위의 예를 단계별로 실행하는 것이 좋습니다.