미리 생성된 매핑 뷰

Entity Framework에서 쿼리를 실행하거나 데이터 원본에 대한 변경 내용을 저장하려면 먼저 데이터베이스에 액세스하기 위한 매핑 뷰 집합을 생성해야 합니다. 이러한 매핑 뷰는 추상적인 방식으로 데이터베이스를 나타내는 Entity SQL 문 집합이며 애플리케이션 도메인별로 캐시되는 메타데이터의 일부입니다. 동일한 애플리케이션 도메인에 동일한 컨텍스트 인스턴스를 여러 개 만들면 각 인스턴스에서 매핑 뷰를 다시 생성하지 않고 캐시된 메타데이터의 매핑 뷰를 다시 사용합니다. 매핑 뷰 생성은 첫 번째 쿼리를 실행하기 위한 전체 비용의 큰 부분을 차지하므로 Entity Framework를 사용하여 매핑 뷰를 미리 생성한 다음 컴파일된 프로젝트에 포함할 수 있습니다. 자세한 내용은 성능 고려 사항(Entity Framework)을 참조하세요.

EF Power Tools Community Edition을 사용하여 매핑 뷰 생성

뷰를 미리 생성하는 가장 쉬운 방법은 EF Power Tools Community Edition을 사용하는 것입니다. Power Tools가 설치되면 아래와 같이 보기 생성 메뉴 옵션이 있습니다.

  • Code First 모델의 경우 DbContext 클래스가 포함된 코드 파일을 마우스 오른쪽 단추로 클릭합니다.
  • EF 디자이너 모델의 경우 EDMX 파일을 마우스 오른쪽 단추로 클릭합니다.

generate Views

프로세스가 완료되면 다음과 유사한 클래스가 생성됩니다.

generated Views

이제 애플리케이션을 실행할 때 EF는 필요에 따라 이 클래스를 사용하여 뷰를 로드합니다. 모델이 변경되고 이 클래스를 다시 생성하지 않으면 EF에서 예외가 throw됩니다.

코드에서 매핑 뷰 생성 - EF6 이상

뷰를 생성하는 다른 방법은 EF에서 제공하는 API를 사용하는 것입니다. 이 메서드를 사용하는 경우 원하는 방식으로 뷰를 자유롭게 직렬화할 수 있지만 뷰를 직접 로드해야 합니다.

참고 항목

EF6 이상부터만 - 이 섹션에 표시된 API는 Entity Framework 6에 도입되었습니다. 이전 버전을 사용하는 경우 이 정보는 적용되지 않습니다.

뷰 생성

뷰를 생성하는 API는 System.Data.Entity.Core.Mapping.StorageMappingItemCollection 클래스에 있습니다. ObjectContext의 MetadataWorkspace를 사용하여 컨텍스트에 대한 StorageMappingCollection을 검색할 수 있습니다. 최신 DbContext API를 사용하는 경우 아래와 같이 IObjectContextAdapter를 사용하여 이에 액세스할 수 있으며, 이 코드에는 dbContext라는 파생 DbContext 인스턴스가 있습니다.

    var objectContext = ((IObjectContextAdapter) dbContext).ObjectContext;
    var  mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace
                                                                        .GetItemCollection(DataSpace.CSSpace);

StorageMappingItemCollection이 있으면 GenerateViews 및 ComputeMappingHashValue 메서드에 액세스할 수 있습니다.

    public Dictionary<EntitySetBase, DbMappingView> GenerateViews(IList<EdmSchemaError> errors)
    public string ComputeMappingHashValue()

첫 번째 메서드는 컨테이너 매핑의 각 뷰에 대한 항목이 있는 사전을 만듭니다. 두 번째 메서드는 단일 컨테이너 매핑에 대한 해시 값을 계산하고 런타임에 뷰가 미리 생성된 이후 모델이 변경되지 않는지 확인하는 데 사용됩니다. 두 메서드의 재정의는 여러 컨테이너 매핑과 관련된 복잡한 시나리오에 대해 제공됩니다.

뷰를 생성할 때 GenerateViews 메서드를 호출한 다음 결과 EntitySetBase 및 DbMappingView를 작성합니다. ComputeMappingHashValue 메서드에서 생성된 해시도 저장해야 합니다.

뷰 로드

GenerateViews 메서드에서 생성된 뷰를 로드하려면 DbMappingViewCache 추상 클래스에서 상속되는 클래스를 EF에 제공할 수 있습니다. DbMappingViewCache는 구현해야 하는 두 가지 메서드를 지정합니다.

    public abstract string MappingHashValue { get; }
    public abstract DbMappingView GetView(EntitySetBase extent);

MappingHashValue 속성은 ComputeMappingHashValue 메서드에서 생성된 해시를 반환해야 합니다. EF가 뷰를 요청하려는 경우 먼저 모델의 해시 값을 생성하고 이 속성에서 반환된 해시와 비교합니다. 일치하지 않으면 EF는 EntityCommandCompilationException 예외를 throw합니다.

GetView 메서드는 EntitySetBase를 수락하고 GenerateViews 메서드에 의해 생성된 사전에서 지정된 EntitySetBase와 연결되어 이에 대해 생성된 EntitySql을 포함하는 DbMappingVIew를 반환해야 합니다. EF가 없는 뷰를 요청하는 경우 GetView는 null을 반환해야 합니다.

다음은 위에서 설명한 대로 Power Tools를 사용하여 생성된 DbMappingViewCache의 추출이며, 여기서는 필요한 EntitySql을 저장하고 검색하는 한 가지 방법이 표시됩니다.

    public override string MappingHashValue
    {
        get { return "a0b843f03dd29abee99789e190a6fb70ce8e93dc97945d437d9a58fb8e2afd2e"; }
    }

    public override DbMappingView GetView(EntitySetBase extent)
    {
        if (extent == null)
        {
            throw new ArgumentNullException("extent");
        }

        var extentName = extent.EntityContainer.Name + "." + extent.Name;

        if (extentName == "BlogContext.Blogs")
        {
            return GetView2();
        }

        if (extentName == "BlogContext.Posts")
        {
            return GetView3();
        }

        return null;
    }

    private static DbMappingView GetView2()
    {
        return new DbMappingView(@"
            SELECT VALUE -- Constructing Blogs
            [BlogApp.Models.Blog](T1.Blog_BlogId, T1.Blog_Test, T1.Blog_title, T1.Blog_Active, T1.Blog_SomeDecimal)
            FROM (
            SELECT
                T.BlogId AS Blog_BlogId,
                T.Test AS Blog_Test,
                T.title AS Blog_title,
                T.Active AS Blog_Active,
                T.SomeDecimal AS Blog_SomeDecimal,
                True AS _from0
            FROM CodeFirstDatabase.Blog AS T
            ) AS T1");
    }

EF가 DbMappingViewCache를 사용하도록 하려면 DbMappingViewCacheTypeAttribute를 사용하여, 만든 컨텍스트를 지정합니다. 아래 코드에서는 BlogContext를 MyMappingViewCache 클래스와 연결합니다.

    [assembly: DbMappingViewCacheType(typeof(BlogContext), typeof(MyMappingViewCache))]

더 복잡한 시나리오의 경우 매핑 뷰 캐시 팩터리를 지정하여 매핑 뷰 캐시 인스턴스를 제공할 수 있습니다. 이 작업은 추상 클래스 System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory를 구현하여 수행할 수 있습니다. 사용되는 매핑 뷰 캐시 팩터리의 인스턴스는 StorageMappingItemCollection.MappingViewCacheFactoryproperty를 사용하여 검색하거나 설정할 수 있습니다.