1

저는 Entity Framework 5, 데이터베이스 마이그레이션 및 ASP 멤버쉽 API를 사용하는 MVC4 응용 프로그램에서 작업하고 있습니다. 내 개발 환경에서는 데이터베이스를 완전히 삭제하고, 패키지 (.zip)를 실행하고, 페이지를 새로 고치고 예상대로 모든 작업을 수행 할 수 있습니다. 데이터베이스가 생성되면 seed 메소드가 호출되고 일부 기본값이 데이터베이스에 고정됩니다.EF 데이터베이스 마이그레이션

정말 쉽고 완벽합니다. 하지만 ..... 그렇습니다. 항상 그렇습니다!

동일한 패키지 (db 연결 문자열 만 변경)를 배포하고 원격 환경에서이 옵션을 실행하면 동작이 변경됩니다. 다시 말하지만, 데이터베이스를 완전히 삭제하고 패키지 (.zip)를 실행하고 페이지를 새로 고치면 데이터베이스가 ASP 멤버쉽 API 테이블만으로 생성됩니다. 내가 연결 문자열을 확인했습니다, 그게 아니라, 원인, 또는 그렇지 않으면 데이터베이스 및 회원 테이블을 만들 수 없습니다.

정말 powershell 인스턴스 인 nuget 패키지 관리자를 사용하고 있지만 프로덕션 환경에서는 사용할 수 없으므로 사용하지 않습니다. 패키지가이 모든 것을 처리하기를 바라며, 테스트 환경에서는 완벽하게 작동합니다.

누구에게 의견이 있습니까? 이것이 혼합 된 마이그레이션 기록의 부작용 일 수 있습니까?

미리 감사드립니다.

+0

두 개의 연결 문자열이있을 가능성이 있습니까? 회원 가입과 신청서 작성 중입니까? – Floremin

+0

좋은 생각이지만, 단지 1. 패키지를 만들 때 변형을 사용하고 있습니다. 그래서 거기에 묻혀있는 무언가가 올바르지 않습니다. 응답에 대해 –

답변

4

기본 MVC4 인터넷 응용 프로그램 프로젝트는 많은 사람들을 망칠뿐입니다. Microsoft는 EF 컨텍스트가 필요한 SimpleMembership 기능을 시연하려고했지만 실제로 나머지 부분을 효과적으로 사용하려면이 부분을 수정해야한다는 상식이 아닙니다.

그래서 Entity Framework의 작동 원리에 대한 약간의 입문서가 내가 이런 일이 일어나는 이유를 분명히하는 데 도움이 될 것입니다.

Entity Framework (버전 5 이상, 6 또는 이후 버전에서 변경 될 수 있음)는 응용 프로그램에 대해 하나의 DbContext 만 허용합니다. 대부분 프로젝트 템플릿과 응용 프로그램의 나머지 부분에 사용하는 컨텍스트에 의해 자동 생성 된 AccountsContext 2 개 이상이 있습니다. 자동 마이그레이션을 해제하고 마이그레이션 생성을 시도한 경우 EF는 유용하게 사용할 컨텍스트를 지정해야한다고 알려줍니다. 그러나 자동 마이그레이션은 Code First의 기본값이며, 거의 사용하지 않도록 설정되어 있으므로 경고가 거의 발생하지 않습니다.

자동 마이그레이션이 활성화되어 있고 기존 데이터베이스가없는 경우 EF는 컨텍스트에서 사용자를 위해 행복하게 (자동으로) 데이터베이스를 만듭니다. 그러나 여러 문맥이 있다면 어떨까요? 글쎄, EF의 또 다른 불쾌한 기능은 데이터베이스를 적시에 생성한다는 것입니다. 따라서 어떤 컨텍스트가 사용되는지는 먼저 액세스되는 컨텍스트입니다. 좋았어? 따라서 로그온과 같은 작업을 수행하려고 시도하면 데이터베이스가 AccountsContext에서 생성되고 응용 프로그램 컨텍스트에서 액세스하려고하면 데이터베이스가 이미 존재하며 EF는 이 아닌입니다.

그럼 어떻게해야합니까? 모호성을 제거하려면 컨텍스트가 필요합니다. 앱에 원한다면 여전히 둘 이상의 컨텍스트를 가질 수 있지만, 모든 다른 컨텍스트가 데이터베이스 우선이라는 EF에게 필수적으로 말해야합니다. 즉, 아무 것도하지 마십시오.

public class AccountsContext : DbContext 
{ 
    public AccountsContext() 
     : base("name=YourConnectionStringName") 
    { 
     Database.SetInitializer<AccountsContext>(null); 
    } 

    ... 
} 

public class MyAppContext : DbContext 
{ 
    public MyAppContext() 
     : base("name=YourConnectionStringName") 
    { 
    } 

    // All your entities here, including stuff from AccountsContext 

} 

MyAppContext는 EF 알아야 데이터베이스의 모든 개체가됩니다 "마스터"상황이 될 것입니다. base을 호출하면 EF의 추측을 벗어나 모든 사람이 데이터베이스 연결을 사용해야하는 페이지와 동일한 페이지임을 명시 적으로 확인합니다.AccountsContext은 이제 기본적으로 데이터베이스 우선이므로 데이터베이스를 만들거나 마이그레이션을 시도하는 EF를 촉발시키지 않습니다. 즉 MyAppContext이 대상입니다. AccountsContext과 같은 방식으로 다른 컨텍스트를 만들어 앱의 기능을 해할 수 있습니다. DbSet 속성 선언을 "마스터"컨텍스트로 미러링하면됩니다.

Julie Lehrman은 그녀의 저서 Programming Entity Framework: DbContext에서 "경계 된 컨텍스트"라는 개념을 호출하고 "경계 된 컨텍스트"를 모두 상속 할 수있는 제네릭 클래스를 제공하므로 연결 문자열 이름을 지정하거나 설정할 필요가 없습니다 매회, 데이터베이스 초기화자가 null.

+0

에 감사드립니다. 계정 컨텍스트 db를 만들기 위해 호출을 추가했는데 왜 그 것이 한 환경에서 잘 작동하고 다른 환경에서는 정상적으로 작동하지 않습니까? 바라건대 이번 주에이 변화를 시험 할 기회를 갖게 될 것이고 그때까지 계속 될 것입니다 –

+0

내가 틀릴 수도 있지만 내 대답의 요점을 놓친 것 같습니다. 하나의 컨텍스트 또는 다른 컨텍스트가 먼저 실행되는지 확인하는 것은 중요한 문제를 해결하지 못합니다. 둘 이상의 컨텍스트를 마이그레이션 할 수 없으므로 계정 컨텍스트가 먼저 실행되면 다른 모든 응용 프로그램 모델 중 데이터베이스에 테이블이 생성되지 않습니다. 그 안에 모든 것을 담은 하나의 컨텍스트가 있어야하고, 가지고있는 컨텍스트를 모두 비활성화해야합니다. –

+0

마침내 이것을 시험 할 기회가 있었고, 당신이 옳은 것처럼 보였습니다 ... 첫 번째 요청에 따라 두 컨텍스트 중 하나만 실행됩니다. 다음 주에 제안 된 변경 사항으로 코드를 실행할 수있는 기회가 주어질 것입니다. 문제를 해결해야합니다. 나는이 질문을 답으로 표시 할 것입니다. 제가 여전히 붙어있는 유일한 이유는 왜 이것이 정상적으로 작동하는지입니다 내 테스트 환경에서? –