Каковы недостатки в отключении ProxyCreationEnabled для CTP5 кода EF в первую очередь - PullRequest
79 голосов
/ 04 января 2011

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

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

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

Ответы [ 4 ]

70 голосов
/ 04 января 2011

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

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

67 голосов
/ 08 ноября 2013

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

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

10 голосов
/ 18 января 2014

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

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

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

5 голосов
/ 27 октября 2017

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

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

Так! Если вы посмотрите на свою модель, у вас есть файл .tt в вашем файле .edmx. Этот файл .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

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

...