首先关闭EF代码的CTP5的ProxyCreationEnabled有什么缺点

时间:2011-01-04 17:11:09

标签: c# entity-framework wcf serialization proxy-classes

我的WCF服务可以从代码优先模型返回类的唯一方法是使用下面的代码将ProxyCreationEnable设置为false

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

这样做的负面后果是什么?一个好处是我至少可以将这些动态类型序列化,以便可以使用WCF通过线路发送它们。

4 个答案:

答案 0 :(得分:70)

动态代理用于更改跟踪和延迟加载。当WCF尝试序列化对象时,通常会关闭并处理相关上下文,但导航属性的序列化将自动触发延迟加载(在封闭上下文中)=>例外。

如果关闭延迟加载,则需要对要使用的所有导航属性使用预先加载(包含在ObjectQuery上)。跟踪更改不适用于WCF,它仅适用于修改附加到ObjectContext的实体。

答案 1 :(得分:67)

如果DbContext.Configuration.ProxyCreationEnabled设置为false,则除非在父对象上调用Include方法,否则DbContext不会加载某些父对象的子对象。将DbContext.Configuration.LazyLoadingEnabled设置为truefalse不会对其行为产生任何影响。

如果DbContext.Configuration.ProxyCreationEnabled设置为true,则会自动加载子对象,DbContext.Configuration.LazyLoadingEnabled值将控制加载子对象的时间。

答案 2 :(得分:10)

使用EF时,默认情况下会为您的类创建代理。解决方案是在DbContext类的构造函数中添加此行。您的数据模型继承自DbContext类,因此您可以像这样编辑模型:

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

此课程位于EF.edmx,然后是yourmodel.Context.tt,然后是yourmodel.Context.cs

答案 3 :(得分:3)

(使用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模板

很容易知道你的T4代码是否犯了错误,因为.cs文件根本就没有制作,或者如果你在编辑器中打开它会有明显的错误。