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

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

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

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


person Ralph Shillington    schedule 04.01.2011    source источник
comment
Служба WCF может возвращать классы из модели с первым кодом - вам действительно не следует использовать типы домена / сущности в качестве DTO в любом случае. DTO не являются бизнес-объектами.   -  person Dai    schedule 08.06.2021


Ответы (4)


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

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

person Ladislav Mrnka    schedule 04.01.2011
comment
Есть ли преимущество в производительности при отключении ProxyCreationEnabled? Я часто беру экземпляр DbContext, например, просто для чтения с нетерпеливой загрузкой. - person Chris Moschini; 18.05.2013
comment
@ChrisMoschini Когда объект POCO не имеет прокси для отслеживания изменений, изменения обнаруживаются путем сравнения содержимого ваших объектов с копией предыдущего сохраненного состояния. Это глубокое сравнение станет длительным процессом, когда у вас много сущностей в вашем контексте или когда ваши сущности имеют очень большое количество свойств, даже если ни одно из них не изменилось с момента последнего сравнения. msdn.microsoft.com/en-us/library /hh949853(v=vs.113).aspx - person Niklas Peter; 17.02.2018

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

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

person Aleksey Timkov    schedule 08.11.2013

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

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

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

person Vicente Zambrano    schedule 17.01.2014
comment
Это не ответ, но мне это все равно помогло. - person Akira Yamamoto; 24.09.2014
comment
У вас есть хорошее предложение, как автоматизировать процесс установки этой строки? Каждый раз, когда я воссоздаю модель, я обязательно забываю установить для свойства значение false, и на отладку могут уйти часы, прежде чем кто-то поймет, что с ней не так. - person Konrad Viltersten; 27.12.2015
comment
@konrad - Создайте код в частичном классе, чтобы он не был переопределен. общедоступный частичный класс yourDataMoldelEntities () - person Mikee; 04.02.2016
comment
@Mikee Серьезно? Я ожидал бы каких-то проблем из-за того, что автоматически сгенерированный конструктор сталкивается с тем, который был написан мной в частичном классе ... - person Konrad Viltersten; 04.02.2016
comment
@konrad они создали частичный класс 'type', чтобы дать вам возможность не перезаписывать ваш код - person Mikee; 04.02.2016
comment
@Mikee Боюсь, что я не совсем понял свое беспокойство. Если у меня есть частичный класс Blobb с конструктором public Blobb () {...} и есть другой файл, содержащий остальную часть частичного класса Blobb < / i>, также содержащий конструктор public Blobb () {...}, код не будет компилироваться. Если один из партиалов генерируется автоматически, программисту придется вручную исправлять этот файл каждый раз, когда происходит автогенерация. Правильный? Или есть простой способ справиться с этим, о котором я не знаю? Пожалуйста, просветите меня. Я фанат плавных способов, хе-хе. - person Konrad Viltersten; 05.02.2016
comment
@KonradViltersten Просто перегрузите конструктор, изменив подпись вашего конструктора. Вы можете сделать это, добавив фиктивный параметр, например public Blobb(bool dummy = true){...}. Лично я использую public Blobb(string connectionString) : base(connectionString), потому что мне не нравится хранить учетные данные в моем файле AppSettings. - person Dan Bechard; 27.04.2017

(Используя Visual Studio 2013 или новее)

Чтобы избежать редактирования конструктора класса в вашей модели EF каждый раз, когда вы обновляете модель из базы данных или каким-либо другим способом запускаете перестроение кода, правильное место для внесения изменений находится в файле кода T4, который отвечает за собственно создание кода модели. Несколько лет назад у меня была еще одна проблема с динамическими свойствами, когда я понял основную механику создания классов и свойств. Т4 !!! Какое это чудо: -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 будет либо вообще не создан, либо с очевидными ошибками, если вы откроете его в редакторе.

person Per Malmstedt    schedule 27.10.2017
comment
Ничего себе - это действительно должно быть предпочтительным решением, поскольку оно устраняет проблему в корне. А также дает хорошее представление о взаимосвязи файла * .tt с результирующим файлом * .cs. - person Douglas Timms; 29.06.2019