먼저 EF 코드의 CTP5에 대해 ProxyCreationEnabled를 끄는 단점은 무엇입니까?


82

내 WCF 서비스가 코드 우선 모델에서 클래스를 반환 할 수있는 유일한 방법은 아래 코드 ProxyCreationEnablefalse사용하여를 로 설정하는 것 입니다.

((IObjectContextAdapter)MyDb).ObjectContext.ContextOptions.ProxyCreationEnable = false;

이렇게하면 부정적인 결과는 무엇입니까? 한 가지 이점은 최소한 이러한 동적 유형을 직렬화하여 WCF를 사용하여 유선으로 전송할 수 있다는 것입니다.

답변:


71

동적 프록시는 변경 내용 추적 및 지연로드에 사용됩니다. WCF가 개체를 직렬화하려고 할 때 관련 컨텍스트는 일반적으로 닫히고 삭제되지만 탐색 속성의 직렬화는 자동으로 지연로드 (닫힌 컨텍스트에서) => 예외를 트리거합니다.

지연로드를 끄면 사용하려는 모든 탐색 속성에 대해 즉시로드를 사용해야합니다 (ObjectQuery에 포함). 변경 내용 추적은 WCF에서 작동하지 않으며 ObjectContext에 연결된 엔터티를 수정하는 경우에만 작동합니다.


7
ProxyCreationEnabled를 비활성화하면 성능상의 이점이 있습니까? 예를 들어 eager loading으로 읽기를 수행하기 위해 DbContext 인스턴스를 자주 가져옵니다.
Chris Moschini

2
@ChrisMoschini "POCO 엔터티에 변경 추적 프록시가없는 경우 엔터티의 내용을 이전에 저장된 상태의 복사본과 비교하여 변경 사항을 찾습니다. 컨텍스트에 엔터티가 많은 경우이 심층 비교는 긴 프로세스가됩니다. , 또는 엔터티에 매우 많은 양의 속성이있는 경우 마지막 비교가 발생한 이후 변경된 사항이 없더라도. " msdn.microsoft.com/en-us/library/hh949853(v=vs.113).aspx
Niklas Peter

75

가로 DbContext.Configuration.ProxyCreationEnabled설정 되면 false부모 개체에서 Include메서드가 호출 되지 않는 한 DbContext는 일부 부모 개체에 대한 자식 개체를로드하지 않습니다 . 또는로 설정 DbContext.Configuration.LazyLoadingEnabled하면 동작에 영향을주지 않습니다.truefalse

경우 DbContext.Configuration.ProxyCreationEnabled로 설정되어 true, 자식 개체는 자동으로로드되며, DbContext.Configuration.LazyLoadingEnabled자식 개체가로드 될 때 값을 제어합니다.


10

EF를 사용하면 기본적으로 클래스에 대한 프록시가 생성됩니다. 해결책은 DbContext 클래스의 생성자에이 줄을 추가하는 것입니다. DbContext 클래스에서 상속 된 데이터 모델이므로 다음과 같이 모델을 편집 할 수 있습니다.

    public yourDataModelEntities()
        : base("name=yourDataModelEntities")
    {
        base.Configuration.ProxyCreationEnabled = false;
    }

이 클래스는 당신에 EF.edmx에서 다음 yourmodel.Context.tt다음yourmodel.Context.cs


2
이것은 대답이 아니지만 어쨌든 나를 도왔습니다.
Akira Yamamoto

1
그 라인을 입력하는 과정을 자동화하는 방법에 대한 좋은 제안이 있습니까? 모델을 다시 만들 때마다 속성을 false 로 설정하는 것을 잊을 수밖에 없으며 누군가가 그 문제를 깨닫기 전에 디버깅하는 데 몇 시간이 걸릴 수 있습니다.
Konrad Viltersten 2015

@konrad-재정의되지 않도록 부분 클래스에 코드를 만듭니다. 공공 부분 클래스 yourDataMoldelEntities ()
Mikee

@Mikee 정말? 자동 생성 생성자가 부분 클래스에서 작성한 생성자와 충돌하기 때문에 어떤 종류의 문제가 발생할 수 있습니다.
Konrad Viltersten

@konrad 그들은 코드를 덮어 쓰지 않는 방법을 제공하기 위해 부분 클래스 '유형'을 만들었습니다
Mikee

6

(Visual Studio 2013 이상 사용)

데이터베이스에서 모델을 새로 고칠 때마다 EF 모델에서 클래스 생성자의 편집을 방지하거나 다른 방법으로 코드 재 빌드를 트리거하려면 변경을 수행하는 적절한 위치는 다음을 담당하는 T4 코드 파일에 있습니다. 실제로 모델 코드를 생성합니다. 몇 년 전 클래스와 속성이 실제로 생성되는 방식의 기본 메커니즘을 이해했을 때 동적 속성과 관련된 다른 문제가있었습니다. T4 !!! 그것이 얼마나 기적인가 :-D T4 구문은 처음에는 약간 위협적 일 수 있으므로 구문을 읽는 것이 현명합니다. 변경할 때 매우 집중하는 것도 좋은 생각입니다 :-)

그래서! 모델을 보면 .edmx 파일 아래에 .tt 파일이 있습니다. 이 .tt (T4) 파일은 실제로 모델 클래스를 생성하는 스크립트입니다. 스크립트는 모델을 빌드하거나 모델 편집기에서 일부를 변경할 때마다 자동으로 실행됩니다.

모델 설명 자의 이름이 Model1.edmx 라고 가정 해 보겠습니다 . 그 아래의 트리에 Model1.Context.tt 라는 파일이 있습니다 . Model1.Context.cs 파일 도 볼 수 있습니다. 이것은 분명히 귀하의 컨텍스트에 대한 실제 코드 파일입니다. 그러나이 파일은 .tt 스크립트 파일이 실행 된 결과입니다 ! 완전히 동적으로 생성됩니다. 그래서 그것을 편집 할 생각이 없습니다.

.tt 파일을 열면 다음과 같은 내용이 표시됩니다.

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
 output extension=".cs"#><#

const string inputFile = @"Model1.edmx";
var textTransform = DynamicTextTransformation.Create(this);
..
..

또 다른 50 줄이 내려 가면 생성자 코드가 스크립팅되고 있습니다.

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
<#
}
#>

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
    {
        public <#=code.Escape(container)#>()
            : base("name=<#=container.Name#>")
        {
        base.Configuration.ProxyCreationEnabled = false;
    <#
    if (!loader.IsLazyLoadingEnabled(container))
    {
    #>
            this.Configuration.LazyLoadingEnabled = false;
    <#
    }

base.Configuration.ProxyCreationEnabled = false;생성자의 첫 번째 줄이되 도록 속성을 추가했습니다 .

파일을 저장하고 Model1.Context.cs 파일을 열어 결과 코드를 확인합니다. 템플릿 스크립트를 강제로 실행하려면 메뉴를 선택하십시오.

빌드-모든 T4 템플릿 변환

.cs 파일이 전혀 생성되지 않거나 편집기에서 열면 명백한 오류가 발생하므로 T4 코드에서 실수를했는지 쉽게 알 수 있습니다.


와우-이것은 루트에서 문제를 해결하기 때문에 실제로 선호되는 솔루션이어야합니다. 또한 * .tt 파일과 결과 * .cs 파일의 관계에 대한 좋은 배경 정보를 제공합니다.
Douglas Timms 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.