2012-02-18 3 views
41

기존 데이터베이스에서 Entity Framework 4.3을 사용하고 있으며 몇 가지 시나리오를 준비하고 있습니다.Entity Framework 4.3의 데이터를 점진적으로 시드하는 가장 좋은 방법

첫 번째로 데이터베이스를 삭제하면 EF에서 처음부터 다시 작성하고 싶습니다. CreateDatabaseIfNotExists 데이터베이스 초기화 프로그램을 성공적으로 사용했습니다.

둘째, 모델을 업데이트하고 데이터베이스가 이미 존재하면 데이터베이스가 자동으로 업데이트되기를 원합니다.이 작업을 성공적으로 수행했습니다.

여기 내 질문이 있습니다. 내 모델에 일부 참조 데이터가 필요한 새 테이블을 추가한다고 가정 해 봅시다. 데이터베이스 초기화 도구가 실행될 때 및 마이그레이션이 실행될 때이 데이터가 생성되도록하는 가장 좋은 방법은 무엇입니까? 내 욕망은 처음부터 db를 만들 때 데이터가 생성되고 마이그레이션 실행의 결과로 데이터베이스가 업데이트되는 경우입니다.

일부 EF 마이그레이션 예에서는 마이그레이션의 UP 메서드에서 SQL() 함수를 사용하여 시드 데이터를 만드는 것을 보았지만 가능한 경우 시드 데이터를 만들 때 컨텍스트를 사용합니다. 데이터베이스 이니셜 라이저 예제) EF의 전체 아이디어가 추상화되면 순수 SQL을 사용한다는 것이 나에게 이상한 것처럼 보인다. UP 메서드에서 컨텍스트를 사용하려고했지만 어떤 이유로 테이블에서 호출하기 바로 아래에 시드 데이터를 추가하려고 할 때 마이그레이션에서 만들어진 테이블이 존재하지 않는다고 생각하지 않았습니다.

모든 지혜가 매우 감사하겠습니다.

답변

53

엔티티를 사용하여 데이터를 시드하려는 경우 마이그레이션 구성에서 Seed 메서드를 사용해야합니다. 매우 기본적인 시드에 사용하도록되어 있기 때문에 마이그레이션 종자 데이터를 매우 효율적이지 얼마나

internal sealed class Configuration : DbMigrationsConfiguration<YourContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
    } 

    protected override void Seed(CFMigrationsWithNoMagic.BlogContext 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" } 
     // ); 
     // 
    } 
} 

방법 : 당신은 당신이이 구성 클래스를 얻을 것이다 Enable-Migrations 신선한 프로젝트를 생성합니다. 새 버전에 대한 모든 업데이트는 전체 세트를 거쳐 기존 데이터를 업데이트하거나 새 데이터를 삽입하려고합니다. AddOrUpdate 확장 방법을 사용하지 않는 경우 데이터가 아직 존재하지 않는 경우에만 데이터베이스에 데이터를 시드해야합니다. 당신은 당신이 일반적으로 더 나은 결과를 얻을 것이다 데이터의 O를 많은 종자해야하기 때문에

당신은 파종을위한 효율적인 방법을 원하는 경우 :

public partial class SomeMigration : DbMigration 
{ 
    public override void Up() 
    { 
     ... 
     Sql("UPDATE ..."); 
     Sql("INSERT ..."); 
    } 

    public override void Down() 
    { 
     ... 
    } 
} 
+8

실제로 Up 메서드에서 컨텍스트를 만들고 AddOrUpdate를 사용하여 행을 삽입 할 수 있습니다. 그러나 마이그레이션 트랜잭션에 래핑되지 않으므로 문제가 발생할 수 있습니다. 또한 모델이 변경 될 때 나중에 컴파일하는 것이 보장되지 않습니다. – Betty

+0

Up 메서드에서 컨텍스트를 만들려고했지만 테이블이 존재하지 않는다는 오류가 발생했습니다. 나는 "Up"방법으로 SQL을 시도 할 것이다. –

+8

@ 라디 슬라브 (Ladislav) EF에 대한 깊이있는 지식은 계속 저를 놀라게합니다. 주제에 관한 책을 저술 해 본 경험이 있거나 흔히 접하게되는 일반적인 오해를 해결해 보았습니까? – kingdango

32

내가 당신 Up() 방법에 Sql() 전화를 사용하는 것이 좋습니다 않을 것을 때문에 (IMO) 이것은 실제로 시드 코드가 아닌 내장 함수가없는 실제 이주 코드 용입니다.

시드 데이터를 미래에 변경 될 수있는 것으로 생각하고 싶습니다 (내 스키마가 없어도). 그래서 시드 함수의 모든 삽입에 "방어적인"체크를 써서 수술은 이전에 발사되지 않았다.

"유형"테이블이 3 개의 항목으로 시작되지만 나중에 네 번째를 추가하는 시나리오를 고려하십시오. 이 문제를 해결하기 위해 "마이그레이션"이 필요하지 않습니다.

Seed()을 사용하면 Ladyslav가 시연 한 Sql() 메서드에서 일반 SQL 문자열을 사용하는 것보다 훨씬 더 멋진 작업을 할 수 있습니다.

또한 마이그레이션 코드와 시드 코드에 기본 제공 EF 메서드를 사용하면 데이터베이스 작업이 플랫폼 중립적으로 유지된다는 이점이 있습니다. 이것은 스키마 변경과 쿼리가 Oracle, Postgre 등에서 실행될 수 있음을 의미합니다. 실제 원시 SQL을 작성하면 불필요하게 자신을 잠글 수 있습니다.

EF를 사용하는 사람 중 90 %가 SQL Server를 사용하기 때문에 걱정할 필요는 없습니다.하지만 솔루션에 대한 다른 관점을 제공하기 위해 SQL Server를 사용하는 사람이 90 %에 불과할 것이므로 걱정하지 않아도됩니다.

+7

"위로"방법은 "참조"데이터를 수행하기에 좋은 장소라고 생각합니다. 참조 데이터는 일반적으로 응용 프로그램이 일종의 논리를 위해 해당 데이터를 필요로 함을 의미합니다. – nootn