首先关闭 EF 代码的 CTP5的 ProxyCreationEnable 的缺点是什么

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

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

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

54190 次浏览

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

如果关闭延迟加载,则需要对要使用的所有导航属性(Include on ObjectQuery)使用即时加载。跟踪更改不能在 WCF 上工作,它只能用于修改附加到 ObjectContext 的实体。

如果将 DbContext.Configuration.ProxyCreationEnabled设置为 false,则 DbContext 将不会为某个父对象加载子对象,除非对父对象调用 Include方法。将 DbContext.Configuration.LazyLoadingEnabled设置为 truefalse对其行为没有影响。

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

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

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

这个类在你的 EF.edmx中,然后在 yourmodel.Context.tt中,然后在 yourmodel.Context.cs

(使用 VisualStudio2013或更高版本)

为了避免每次从数据库中刷新模型时对 EF 模型中的类构造函数进行编辑,或者以其他方式触发代码的重建,进行更改的适当位置是负责实际创建模型代码的 T4代码文件。 几年前,当我理解了类和属性实际上是如何创建的基本机制时,我还遇到了一些动态属性的其他问题。T4! ! !真是个奇迹 T4语法一开始可能有点吓人,所以阅读语法是明智的。在做出改变时非常专注也是一个好主意: -)

那么!如果你看你的模型,你有一个。你名下的文件。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 文件查看结果代码。 如果要强制运行模板脚本,请选择菜单

Build-转换所有 T4模板

很容易知道您是否在 T4代码中犯了错误,因为。Cs 文件要么根本不生成,要么如果在编辑器中打开它,就会出现明显的错误。