2011-04-19 44 views
0

我正在使用Entity Framework 4,并且我发现当我点击浏览器上的后退按钮导航到之前重定向的页面时该页面将打开,但是当我重新提交它的形式,我得到了各种奇怪的错误如,EntityFramework - 点击后退按钮并重新提交会导致错误

“的实体对象不能由IEntityChangeTracker

的多个实例引用的问题是如何可以重新提交表单创建这样的错误,据我所知,每个请求新创建一个新的数据库上下文?我可以看到它们在调试器中被创建为新的!

之前的附加代码的运行我的背景下审视,看是否被连接已加入的实体,这就是它说...

context.Entry(实体);

{System.Data.Entity.Infrastructure.DbEntityEntry`1[Entities.Orders.Order]} 
CurrentValues: 'context.Entry(entity).CurrentValues' threw an exception of type 'System.InvalidOperationException' 
Entity: {Entities.Orders.Order} 
OriginalValues: 'context.Entry(entity).OriginalValues' threw an exception of type 'System.InvalidOperationException' 
State: Detached 

其“独立”那么,为什么我安装的实体时出现错误?

干杯,伊恩。

+2

上下文不是线程安全的。你没有任何机会缓存这个背景吗?你是否在完成时处理上下文? – 2011-04-19 17:02:17

+0

不,我没有明确地处理它们,但正如我所说的,我可以看到它们在调试器中被刷新了。 – 2011-04-19 18:09:22

+0

我最近在参加一个会议,有人提出了一个奇怪的问题,如果我回想起来,他们与上下文交叉请求。只是为了让终结者的神灵快乐,把它包装在一个使用声明中来处置它,然后再试一次。它可能不会改变任何事情,只是一个体面的起点。任何实现IDisposable的东西都应该被丢弃。另外,因为它们是新的并不意味着没有任何静态的剩余信息(我不确定内部 - 只是说一个新的对象不能保证100%干净的状态 - 尤其是如果在幕后它使用线程上下文,等) – 2011-04-19 20:29:24

回答

1

该错误并未说明实体是由您的新上下文加载的。该错误说实体认为它被附加到另一个上下文 - 可能是您之前的请求中已经可以处理的那个上下文。这是动态代理的一些不良行为 - 即使它被丢弃,它们仍旧引用旧的上下文。避免这种情况的唯一方法是不使用代理(=不使用延迟加载和动态更改跟踪),或者手动分离将破坏对象图的实体(导航属性将为空)。

这是怎么发生的?你是否将实体存储在某个地方(例如在会话中)?一旦您将实体附加到上下文,然后点击后退按钮,您的会话将包含无法附加到另一个上下文的实体。

+0

嗨,我在ASP.net MVC过滤器中加载实体,然后将其分配给控制器基类。控制器然后将实体传递给使用_different_ context的服务。在注入上下文时,我似乎通过使用“每个Web请求”生命周期管理器来清除错误。它仍然看起来很奇怪,但我应该只在按下后退按钮并重新提交时才会出现此错误,而不是正常的页面使用。 – 2011-04-20 09:14:35