1

두 서비스 프로젝트간에 공유되는 어셈블리에 DbContext가 있습니다. 두 프로젝트 모두 Visual Studio에서 디버깅을 시작하도록 설정했습니다. 이로 인해 각 서비스의 DatabaseInitializer이 시작할 때 데이터베이스를 업데이트하려고하는 경쟁 조건이 만들어집니다.DatabaseInitializer를 명시 적으로 호출

이를 방지하기 위해 DbContext을 다음과 같이 수정하여 DatabaseIntializer이 자동으로 등록되지 않도록했습니다.

public EntityContext : DbContext 
{ 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     Database.SetInitializer<EntityContext>(null); 
    } 
} 

나는 OnModelCreating() 듯 무시하고 무슨 일이 있었 모든 프로젝트에서 SetInitializer() 호출 내 DbContext를 참조 할 수 있음을 복제하지 않았을 수 있도록 DbContext 자체 내부의 DatabaseInitializer을 해제 원했고, 내가 읽은 것 내용에 따라 그것을하는 방법이기 위하여.

이렇게하면 DatabaseInitializer이 자동으로 실행되는 것을 방지 할 수 있지만 데이터베이스를 업데이트하기 위해 수동으로 실행할 수있는 별도의 프로젝트를 만들고 싶습니다. 그래서 다음과 같은 일을했다 :

static void Main(string[] args) 
{ 
    Database.SetInitializer(new CreateDatabaseIfNotExists<EntityContext>()); 
    new EntityContext().Database.Initialize(true); 
} 

문제는이 작동하지 않습니다합니다 - OnModelCreating() 방법에 설정된 널 초기화 분명히 내가 SetInitializer()에 다른 전화에서 지정하는 것을 우선합니다. SetIntializer(null) 호출을 EntityContext 클래스의 정적 생성자로 이동하여 먼저 호출되도록 보장하기 위해 여전히 작동하지 않습니다.

static void Main(string[] args) 
{ 
    new CreateDatabaseIfNotExists<EntityContext>() 
     .InitializeDatabase(new EntityContext()); 
} 

을하지만 엔티티 프레임 워크 인프라가 그에게 전화하기로함에 따라 DatabaseInitializer.InitializeDatabase()를 호출하면 바로 바로 보이지 않는다 : 나는 다음과 같이 수동으로 초기화를 호출하는 경우 작동하는 유일한 방법입니다.

EF Code First의 버그입니까? 이 문제를 해결하는 "올바른"방법은 무엇입니까?

업데이트 : Update-Database 패키지 관리자 콘솔 명령으로 데이터베이스 스크립트를 수동으로 만드는 것이 프로그래밍 방식으로 데이터베이스를 업데이트하려고 시도하는이 kludgey 프로젝트보다 더 나은 솔루션이라고 판단되었습니다.

답변

1

이니셜 라이저를 설정하기위한 호출이 이니셜 라이저를 사용하지 않도록 설정 한 후에 수행되어야합니다. OnModelCreating 또는 정적 EntityContext 이니셜 라이저는 사용자의 경우에 그렇게하지 않습니다. 정적 이니셜 라이저는 EntityContext를 처음 사용할 때만 호출되며,이 예제에서는 SetInitializer를 호출 한 후에야 EntityContext를 호출합니다.

SetInitializer 호출을 만들기 전에 정적 초기화 프로그램을 호출하는 것을 고려할 수 있습니다. 예를 들어,이 작동해야합니다 :

using (var context = new EntityContext()) 
{ 
    Database.SetInitializer(new CreateDatabaseIfNotExists<EntityContext>()); 
    context.Database.Initialize(true); 
} 
+0

멋진 catch ...하지만 심지어 코드는 정적 생성자 경로를 이동하는 경우에만 작동합니다. 그 이유는 실제로 OnModelCreated()에 대한 호출을 트리거하는'Initialize()'호출이기 때문입니다. 나는 이제 이니셜 라이저를 직접 호출하는 것이 나의 의도를 더 잘 표현할 수 있다는 생각에 기대고있다. – luksan

+1

DbContext는 의도적으로 매우 게으르며 사용자가 실제로 어떤 방법으로 사용하기 전까지 초기화를 포함하여 거의 작동하지 않기 때문입니다. 즉, (perf 관점에서) 인스턴스를 생성하기 전에 DbContext를 사용할 필요가 없다는 것을 알 수 있습니다. 매우 유용 할 수 있습니다. –

관련 문제