我应该使用实体框架 4.1 和 MVC3 启用还是禁用动态代理? [英] Should I enable or disable dynamic proxies with entity framework 4.1 and MVC3?

查看:20
本文介绍了我应该使用实体框架 4.1 和 MVC3 启用还是禁用动态代理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以提供一些建议或指出一些有助于做出此决定的博客/文章吗?代理对我来说似乎很陌生,我很犹豫要不要使用它们.我喜欢通过在我的模型中使用虚拟属性来控制延迟加载的能力,但这几乎是我能看到的所有好处.我的应用程序是一个简单的 MVC Web 应用程序,当实体经历状态更改时,我不需要将任何挂钩连接到上下文中.

Could someone offer up some advice or point out some blogs/articles that could help with making this decision? The proxies seem very foreign to me and I'm hesitant to use them. I like the ability to control Lazy Loading by using virtual properties in my model, but that's pretty much all the benefits that I can see. My application is a simple MVC web application and I don't need to wire up any hooks into the context for when the entities experience a changed state.

无论如何,这是我现在非常有限的利弊列表,如果我对其中任何一个不满意,请告诉我.

Anyway, here's my very limited list of pros and cons right now, let me know if I'm off base with any of this.

优点

  • 在保存"或更新"时,我可以无缝地使用应用"更改
  • 延迟加载配置非常简单.

缺点

  • 我的实体之前从未使用过代理,这是在对我自己和其他团队来说似乎不舒服的方法成员.
  • 难以调试.
  • 如果我想序列化/反序列化需要额外的代码
  • 在保存"或更新"时,代理必须与从上下文中检索到的对象相同.

推荐答案

如果说 EF 中的动态代理,有两种不同的类型需要区分:

If you talk about dynamic proxies in EF there are two different types to distinguish:

  • 延迟加载的代理
  • 变更跟踪代理

通常变更跟踪代理也可以作为延迟加载的代理.反过来就不对了.这是因为对变更跟踪代理的要求更高,尤其是所有属性——还有标量属性——必须是virtual.对于延迟加载,导航属性是 virtual 就足够了.

Usually a change tracking proxy also can serve as a proxy for lazy loading. The reverse is not true. This is because the requirements for change tracking proxies are higher, especially all properties - also the scalar properties - must be virtual. For lazy loading it is enough that the navigation properties are virtual.

更改跟踪代理始终允许利用延迟加载这一事实是 DbContext 具有此配置标志的主要原因:

The fact that a change tracking proxy always also allows to leverage lazy loading is the main reason why the DbContext has this configuration flag:

DbContext.Configuration.LazyLoadingEnabled

这个标志默认为真.即使创建了代理,将其设置为 false 也会禁用延迟加载.如果您正在使用更改跟踪代理但又不想将这些代理用于延迟加载,则这一点尤其重要.

This flag is true by default. Setting it to false disables lazy loading even if proxies are created. This is especially important if you are working with change tracking proxies but don't want to use those proxies for lazy loading as well.

选项...

DbContext.Configuration.ProxyCreationEnabled

... 完全禁用代理创建 - 也用于更改跟踪和延迟加载.

... disables proxy creation completely - for change tracking and lazy loading as well.

只有当您的实体类满足创建更改跟踪或延迟加载代理的要求时,这两个标志才有意义.

Both flags only have a meaning at all if your entity classes meet the requirements for creating either change tracking or lazy loading proxies.

现在,您知道动态延迟加载代理的用途了.那么,为什么要使用动态更改跟踪代理?

Now, you know the purpose of dynamic lazy loading proxies. So, why should one use dynamic change tracking proxies?

实际上,我知道的唯一原因是性能.但这是一个非常有力的理由.将基于快照的更改跟踪与基于代理的更改跟踪进行比较,性能差异是巨大的——根据我的测量,50 到 100 的因子是现实的(取自一种方法,该方法需要大约 1 小时才能使用基于快照的更改跟踪和 30 到 60 秒的 10000 个实体在将所有属性设为虚拟以启用更改跟踪代理之后).如果您有一些应用程序可以处理和更改许多(比如超过 1000 个)实体,这将成为一个重要因素.在 Web 应用程序中,您可能只对 Web 请求中的单个实体进行创建/更改/删除操作,这种差异并不重要.

Actually the only reason I am aware of is performance. But this is a very strong reason. Comparing snapshot based change tracking with proxy based change tracking the performance difference is huge - from my measurements a factor of 50 to 100 is realistic (taken from a method which needed around one hour for 10000 entites with snapshot based change tracking and 30 to 60 seconds after making all properties virtual to enable change tracking proxies). This is getting an important factor if you have some application which processes and changes many (say more than 1000) entities. In a web application where you possibly only have Create/Change/Delete operations on single entities in a web request this difference doesn't matter so much.

在几乎所有情况下,如果您不想使用延迟加载代理,您都可以利用预先加载或显式加载来实现相同的目标.基于代理的延迟加载或基于非代理的显式加载的性能是相同的,因为加载导航属性时会发生基本相同的查询 - 在第一种情况下代理执行查询,在第二种情况下您的手写代码.因此,您可以不用延迟加载代理而不会损失太多.

In almost all situations you can leverage eager or explicite loading to achieve the same goal if you don't want to work with lazy loading proxies. The performance for proxy based lazy loading or non-proxy based explicite loading is the same because basically the same query happens when navigation properties are loaded - in the first case the proxy does the query, in the second case your hand-written code. So, you can live without lazy loading proxies without losing to much.

但是,如果您想要合理的性能来处理许多实体,那么除了在 EF 4.0 中使用 EntityObject 派生实体(不是 EF 4.1 中的一个选项,因为它被禁止)之外,别无选择更改跟踪代理当您使用 DbContext) 或根本不使用实体框架时.

But if you want reasonable performance to process many, many entities there is no alternative to change tracking proxies - aside from using EntityObject derived entities in EF 4.0 (not an option in EF 4.1 because it's forbidden when you use DbContext) or not using Entity Framework at all.

编辑(2012 年 5 月)

与此同时,我了解到在某些情况下 与基于快照的跟踪相比,更改跟踪代理的性能并不快,甚至更差.

In the meantime I have learned that there are situations where change tracking proxies are not faster or even worse in performance compared to snapshot based tracking.

由于使用变更跟踪代理时的这些复杂性,首选方法是默认情况下使用基于快照的变更跟踪,并仅在需要高性能且证明速度更快的情况下谨慎使用代理(在进行一些测试后)而不是基于快照的更改跟踪.

Due to these complications when using change tracking proxies, the prefered way is to use snapshot based change tracking by default and use proxies carefully (after doing some tests) only in situations where high performance is required and where they prove to be faster than snapshot based change tracking.

这篇关于我应该使用实体框架 4.1 和 MVC3 启用还是禁用动态代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆