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

发布于 2024-10-10 00:30:24 字数 246 浏览 5 评论 0原文

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

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

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

The only way that my WCF service can return classes from a code first model is by setting the ProxyCreationEnable to false using the code below.

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

What are the negative consequences of doing this? One gain is that I can at least get these dynamic types serialized so they can be sent over the wire using WCF.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

耳根太软 2024-10-17 00:30:24

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

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

If DbContext.Configuration.ProxyCreationEnabled is set to false, DbContext will not load child objects for some parent object unless Include method is called on parent object. Setting DbContext.Configuration.LazyLoadingEnabled to true or false will have no impact on its behaviours.

If DbContext.Configuration.ProxyCreationEnabled is set to true, child objects will be loaded automatically, and DbContext.Configuration.LazyLoadingEnabled value will control when child objects are loaded.

月光色 2024-10-17 00:30:24

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

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

Dynamic proxies are used for change tracking and lazy loading. When WCF tries to serialize object, related context is usually closed and disposed but serialization of navigation properties will automatically trigger lazy loading (on closed context) => exception.

If you turn off lazy loading you will need to use eager loading for all navigation properties you want to use (Include on ObjectQuery). Tracking changes doesn't work over WCF it works only for modification of entity which is attached to ObjectContext.

み格子的夏天 2024-10-17 00:30:24

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

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

该类位于您的 EF.edmx 中,然后位于 yourmodel.Context.tt 中,然后 <代码>yourmodel.Context.cs

When you use EF, it creates a proxy by default for your class. A solution can be to add this line in the constructor of your DbContext class. Your data model inherited from the DbContext class, so you can edit your model like this:

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

This class is in your EF.edmx then in the yourmodel.Context.tt then yourmodel.Context.cs

残月升风 2024-10-17 00:30:24

(使用 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 文件要么根本没有生成,要么在编辑器中打开它时出现明显错误。

(Using Visual Studio 2013 or later)

To avoid the edit of the class constructor in your EF model every time you refresh the model from the database, or some other way trigger the rebuild of the code, the proper place to do the change is in the T4 code file that is responsible of actually creating the model code.
I had some other issue with dynamic properties a few years back when I understood the underlying mechanics of how the classes and properties was actually created. T4!!! What a miracle it is :-D
T4 syntax can be a bit intimidating at first, so reading up on the syntax is wise. Being VERY focused when making changes is also a good idea :-)

So! If you look in your model, you have a .tt file under your .edmx file. This .tt (T4) file is the script that actually creates your model class. The script will be run automatically each time you build your model or make some changes in the model editor.

Let's say your Model descriptor is named Model1.edmx.
You will have a file named Model1.Context.tt in the tree under it. You will also see a Model1.Context.cs file. This is obviously the actual code file for your context. But this file is the result of the .tt script file being run! It is completely dynamically created. So no idea editing it.

Open the .tt file and you will see something like:

<#@ 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);
..
..

Another 50 or so lines down, the constructor code is being scripted.

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;
    <#
    }

I have added the property base.Configuration.ProxyCreationEnabled = false; so that it will be the very first line in the constructor.

Save your file, and open the Model1.Context.cs file to see the resulting code.
If you want to force the template script to run, select the menu

Build - Tranform all T4 templates

It is easy to know if you've made a mistake in your T4 code, as the .cs file will be either not made at all, or with obvious errors if you open it in the editor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文