Share via


코드 기반 구성

참고 항목

EF6 이상만 - 이 페이지에서 다루는 기능, API 등은 Entity Framework 6에 도입되었습니다. 이전 버전을 사용하는 경우 이 정보의 일부 또는 전체가 적용되지 않습니다.

Entity Framework 애플리케이션에 대한 구성은 구성 파일(app.config/web.config) 또는 코드를 통해 지정할 수 있습니다. 후자를 코드 기반 구성이라고 합니다.

구성 파일의 구성은 별도의 문서에 설명되어 있습니다. 이 구성 파일은 코드 기반 구성보다 우선합니다. 즉, 구성 옵션이 코드와 구성 파일 모두에서 설정된 경우 구성 파일의 설정이 사용됩니다.

DbConfiguration 사용

EF6 이상의 코드 기반 구성은 System.Data.Entity.Config.DbConfiguration의 서브클래스를 만들어서 구현됩니다. DbConfiguration을 서브클래싱하는 경우 다음 지침을 따라야 합니다.

  • 애플리케이션에 대해 하나의 DbConfiguration 클래스만 만듭니다. 이 클래스는 앱 도메인 전체 설정을 지정합니다.
  • DbConfiguration 클래스를 DbContext 클래스와 동일한 어셈블리에 배치합니다. (이를 변경하려면 DbConfiguration 이동 섹션을 참조하세요.)
  • DbConfiguration 클래스에 공용 매개 변수가 없는 생성자를 제공합니다.
  • 이 생성자 내에서 보호된 DbConfiguration 메서드를 호출하여 구성 옵션을 설정합니다.

이러한 지침에 따라 EF는 모델에 액세스해야 하는 도구 및 애플리케이션을 실행하는 경우 구성을 자동으로 검색하고 사용할 수 있습니다.

예시

DbConfiguration에서 파생된 클래스는 다음과 같을 수 있습니다.

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;

namespace MyNamespace
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
            SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
        }
    }
}

이 클래스는 실패한 데이터베이스 작업을 자동으로 다시 시도하는 SQL Azure 실행 전략을 사용하고 Code First의 규칙에 따라 생성된 데이터베이스에 로컬 DB를 사용하도록 EF를 설정합니다.

DbConfiguration 이동

DbConfiguration 클래스를 DbContext 클래스와 동일한 어셈블리에 배치할 수 없는 경우가 있습니다. 예를 들어 서로 다른 어셈블리에 각각 두 개의 DbContext 클래스가 있을 수 있습니다. 이를 처리하기 위한 두 가지 옵션이 있습니다.

첫 번째 옵션은 구성 파일을 통해 사용할 DbConfiguration 인스턴스를 지정하는 것입니다. 이를 수행하기 위해 entityFramework 섹션의 codeConfigurationType 특성을 설정합니다. 예시:

<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
    ...Your EF config...
</entityFramework>

codeConfigurationType 값은 DbConfiguration 클래스의 정규화된 어셈블리 및 네임스페이스 이름 이어야 합니다.

두 번째옵션 옵션은 컨텍스트 클래스에 DbConfigurationTypeAttribute를 배치하는 것입니다. 예시:

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}

특성에 전달된 값은 위와 같이 DbConfiguration 형식이거나 어셈블리 및 네임스페이스의 정규화된 형식 이름 문자열일 수 있습니다. 예시:

[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}

명시적으로 DbConfiguration 설정

DbContext 형식을 사용하려면 구성이 필요할 수 있는 경우가 있습니다. 예를 들면 다음과 같습니다.

  • DbModelBuilder를 사용하여 컨텍스트 없이 모델 빌드
  • 애플리케이션 컨텍스트를 사용하기 전에 해당 컨텍스트가 사용되는 DbContext 위치를 활용하는 다른 프레임워크/유틸리티 코드 사용

이러한 상황에서 EF는 구성을 자동으로 검색할 수 없으며 대신 다음 중 하나를 수행해야 합니다.

  • 위의 DbConfiguration 이동 섹션에 설명된 대로 구성 파일의 DbConfiguration 형식을 설정합니다.
  • 애플리케이션 시작 중 정적 DbConfiguration.SetConfiguration 메서드를 호출합니다.

DbConfiguration을 재정의합니다.

DbConfiguration의 구성 집합을 재정의해야 하는 경우가 있습니다. 이는 일반적으로 애플리케이션 개발자가 아니라 파생 DbConfiguration 클래스를 사용할 수 없는 타사 공급자 및 플러그 인에 의해 수행됩니다.

이를 위해 EntityFramework를 사용하면 기존 구성이 잠기기 직전에 수정할 수 있는 이벤트 처리기를 등록할 수 있습니다. 또한 EF 서비스 로케이터에서 반환되는 모든 서비스를 교체하기 위한 sugar 메서드도 제공합니다. 다음은 이를 사용하는 방법입니다.

  • 앱 시작 시(EF를 사용하기 전에) 플러그 인 또는 공급자는 이 이벤트에 대한 이벤트 처리기 메서드를 등록해야 합니다. (애플리케이션에서 EF를 사용하기 전에 이 문제가 발생해야 합니다.)
  • 이벤트 처리기는 교체해야 하는 모든 서비스에 대해 ReplaceService를 호출합니다.

예를 들어 IDbConnectionFactoryDbProviderService를 바꾸려면 다음과 같이 처리기를 등록합니다.

DbConfiguration.Loaded += (_, a) =>
   {
       a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s));
       a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s));
   };

위의 코드에서 MyProviderServicesMyConnectionFactory는 서비스의 구현을 나타냅니다.

종속성 처리기를 추가하여 동일한 효과를 얻을 수도 있습니다.

이러한 방식으로 DbProviderFactory를 래핑할 수도 있지만 이는 EF에만 영향을 미치며 EF 외부의 DbProviderFactory 사용은 영향을 받지 않습니다. 이러한 이유로 이전처럼 DbProviderFactory를 계속 래핑하려고 할 것입니다.

또한 패키지 관리자 콘솔에서 마이그레이션을 실행할 때와 같이 애플리케이션 외부에서 실행하는 서비스도 염두에 두어야 합니다. 콘솔에서 마이그레이션을 실행하면 DbConfiguration을 찾으려고 시도합니다. 그러나 래핑된 서비스를 가져올지 여부는 등록된 이벤트 처리기의 위치에 따라 달라집니다. DbConfiguration 생성의 일부로 등록된 경우 코드가 실행되고 서비스가 래핑되어야 합니다. 일반적으로 이 경우는 그렇지 않으며 이는 도구가 래핑된 서비스를 얻지 못했음을의미합니다.