以编程方式启用/禁用实体代理
我在新项目中使用 Entity Framework 4.1 和 POCO 实体。一切都工作正常,直到我开始使用 AppFabric 缓存来缓存实体。我开始从与反序列化代理对象相关的缓存中检索实体时出现错误。我通过设置 ContextOptions.ProxyCreationEnabled = false 解决了这个问题。 现在的问题是,当我从缓存中获取实体时,我必须使用 ObjectSet.Attach(entity) 将实体附加到当前上下文,并使用 ObjectContext 将它们添加到状态管理器。 ObjectStateManager.ChangeObjectState(entity, EntityState.Modified)。
我的问题是有没有办法以编程方式启用/禁用一组实体的代理?或者换句话说,一种将反序列化实体包装在代理对象中的方法。
如果没有好的方法的话,我现在的做法对吗?或者有更好的方法吗?
I am using the Entity Framework 4.1 with POCO entities in a new project. Everything was working fine until I began caching the entities using AppFabric Caching. I started getting erros retrieving the entitis from the cache related to deserializing the proxy objects. I fixed this problem by setting ContextOptions.ProxyCreationEnabled = false.
The issue now is when I get entities back from the cache, I have to attach the entity to the current context using ObjectSet.Attach(entity) and add them to the state manager using ObjectContext.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified).
My question is is there a way to programmatically enable/disable the proxy for a set of entities? Or in other words a way to wrap the deserialized entity in the proxy object.
If there is not a good way to do this, is the way I am doing it now correct? Or is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在以正确的方式使用它。以编程方式启用或禁用代理创建的唯一方法是将
ContextOptions.ProxyCreationEnabled
设置为false
或true
,就像您目前所做的那样。我认为没有办法将反序列化实体包装到代理对象中。问题在于代理是从实体类型派生的动态创建类型(= 在运行时创建的类型)。因此,如果将其反序列化为实体类型,则无法将其转换为其他类型。
可能有效的方法是使用代理,但禁用 LazyLoading(也在 ContextOptions 中)并手动从加载实体的上下文中分离实体。但它会破坏所有关系,您仍然必须将实体附加到新上下文并设置其状态。另一种可行的解决方案是通过 context.CreateObject 创建新实体,并将所有数据从缓存实体复制到新实体,但这是我不喜欢的解决方案。
换句话说:一旦您使用分离的实体,您必须手动处理附加和设置状态。如果您要更改,情况会更糟关系。
顺便提一句。您提到使用 EFv4.1,但您使用的所有内容都是 EFv4。 EFv4.1 没有对 ObjectContext API 进行任何更改,它添加了不同的 DbContext API,因此除非您将
DbContext
转换回ObjectContext
,否则您正在使用 EFv4。如果将DbContext
强制转换回ObjectContext
,那么您应该检查 DbContext API,因为它提供了Attach
或ChangeObjectState
= 的等效项>DbSet.Attach
和context.Entry(entity).State
。You are using it the correct way. The only way to programatically enable or disable proxy creation is setting
ContextOptions.ProxyCreationEnabled
tofalse
ortrue
as you do at the moment.I don't think there is the way to wrap deserialized entity into proxy object. The problem is that the proxy is dynamically created type (= type created at runtime) derived from your entity type. So if you deserialize it to your entity type you can't cast it to other type.
What can probably work is using proxies but disabling
LazyLoading
(also inContextOptions
) and manually detaching entities from the context which loads them. But it will break all relation and you will still have to attach the entity to the new context and set its state. Another solution which can work is creating new entity bycontext.CreateObject
and copying all data from cached entity to the new one but that is solution which I don't like.Said in other words: Once you are working with detached entities you must deal with attaching and setting state manually. This is even worse if you are going to change relations.
Btw. you mentioned using EFv4.1 but all the stuff you are using is EFv4. EFv4.1 didn't make any change to ObjectContext API, it added different DbContext API so unless you are casting
DbContext
back toObjectContext
you are using EFv4. If you castDbContext
back toObjectContext
then you should check DbContext API because it offers equivalents ofAttach
orChangeObjectState
=>DbSet.Attach
andecontext.Entry(entity).State
.