Каковы недостатки отключения ProxyCreationEnabled для CTP5 кода EF сначала

единственный способ, которым моя служба WCF может возвращать классы из первой модели кода, - это установить ProxyCreationEnable to false используя код ниже.

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

каковы негативные последствия этого? Одно из преимуществ заключается в том, что я могу по крайней мере сериализовать эти динамические типы, чтобы их можно было отправить по проводу с помощью WCF.

4 ответов


динамические прокси используются для отслеживания изменений и отложенной загрузки. Когда WCF пытается сериализовать объект, связанный контекст обычно закрывается и удаляется, но сериализация свойств навигации автоматически запускает ленивую загрузку (в закрытом контексте) => исключение.

Если вы отключите ленивую загрузку, вам нужно будет использовать нетерпеливую загрузку для всех навигационных свойств, которые вы хотите использовать (включая ObjectQuery). Отслеживание изменений не работает над WCF, оно работает только для изменения сущности, которая присоединена к ObjectContext.


если DbContext.Configuration.ProxyCreationEnabled установлено значение false, DbContext не будет загружать дочерние объекты для некоторого родительского объекта, если Include метод вызывается для родительского объекта. Настройка DbContext.Configuration.LazyLoadingEnabled to true или false не будет влиять на его поведение.

если DbContext.Configuration.ProxyCreationEnabled установлено значение true, дочерние объекты будут загружены автоматически, и DbContext.Configuration.LazyLoadingEnabled value будет контролировать, когда загружаются дочерние объекты.


когда вы используете EF, он создает прокси по умолчанию для вашего класса. Решением может быть добавление этой строки в конструктор класса DbContext. Ваша модель данных унаследована от класса DbContext, поэтому вы можете редактировать свою модель следующим образом:

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

этот класс находится в вашем EF.edmx затем в yourmodel.Context.tt затем yourmodel.Context.cs


(С помощью Visual Studio 2013 или более поздней версии)

чтобы избежать редактирования конструктора класса в вашей модели EF каждый раз, когда вы обновляете модель из базы данных или каким-либо другим способом запускаете перестроение кода, правильное место для изменения находится в файле кода T4, который отвечает за фактическое создание кода модели. У меня была другая проблема с динамическими свойствами несколько лет назад, когда я понял основную механику того, как классы и свойства были на самом деле создан. Т4!!! Какое это чудо: - D Синтаксис T4 может быть немного пугающим сначала, поэтому чтение синтаксиса мудро. Быть очень сосредоточенным при внесении изменений также хорошая идея : -)

Так! Если вы посмотрите на свою модель, у вас есть .TT файл под вашим .файл edmx. Это .файл tt (T4) - это скрипт, который фактически создает ваш класс модели. Скрипт будет запускаться автоматически при каждом создании модели или внесении некоторых изменений в Редакторе модели.

скажем, ваша модель дескриптор называется Model1.edmx-файла. У вас будет файл с именем Model1.Контекст.tt на дереве под ним. Вы также увидите Model1.Контекст.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.Контекст.CS файл, чтобы увидеть полученный код. Если вы хотите принудительно запустить сценарий шаблона, выберите меню

Build-Transform все шаблоны T4

легко узнать, если вы допустили ошибку в своем коде T4, как .файл cs будет либо вообще не сделан, либо с очевидными ошибками, если вы откроете его в Редакторе.