我的 WCF 服务可以从代码优先模型返回类的唯一方法是将 设置ProxyCreationEnable
为false
使用下面的代码。
((IObjectContextAdapter)MyDb).ObjectContext.ContextOptions.ProxyCreationEnable = false;
这样做的负面后果是什么?一个好处是我至少可以将这些动态类型序列化,以便可以使用 WCF 通过网络发送它们。
我的 WCF 服务可以从代码优先模型返回类的唯一方法是将 设置ProxyCreationEnable
为false
使用下面的代码。
((IObjectContextAdapter)MyDb).ObjectContext.ContextOptions.ProxyCreationEnable = false;
这样做的负面后果是什么?一个好处是我至少可以将这些动态类型序列化,以便可以使用 WCF 通过网络发送它们。
如果DbContext.Configuration.ProxyCreationEnabled
设置为false
,则 DbContext 不会为某些父对象加载子对象,除非Include
在父对象上调用方法。设置DbContext.Configuration.LazyLoadingEnabled
为true
或false
不会对其行为产生影响。
如果DbContext.Configuration.ProxyCreationEnabled
设置为true
,将自动加载子对象,并且DbContext.Configuration.LazyLoadingEnabled
值将控制何时加载子对象。
动态代理用于更改跟踪和延迟加载。当 WCF 尝试序列化对象时,相关上下文通常会关闭并释放,但导航属性的序列化会自动触发延迟加载(在关闭的上下文中)=> 异常。
如果您关闭延迟加载,您将需要对您想要使用的所有导航属性使用预先加载(包括在 ObjectQuery 上)。跟踪更改不适用于 WCF,它仅适用于修改附加到 ObjectContext 的实体。
当你使用 EF 时,它会默认为你的类创建一个代理。一个解决方案是在 DbContext 类的构造函数中添加这一行。您的数据模型继承自 DbContext 类,因此您可以像这样编辑模型:
public yourDataModelEntities()
: base("name=yourDataModelEntities")
{
base.Configuration.ProxyCreationEnabled = false;
}
这门课在你的EF.edmx
then 在yourmodel.Context.tt
thenyourmodel.Context.cs
(使用 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 文件要么根本不生成,要么在编辑器中打开时出现明显错误。