在application_endrequest上部署对象上下文

时间:2012-06-08 11:26:18

标签: c# asp.net entity-framework

我遇到了EF4对象上下文的问题,我将其存储在 HttpContext.Current.Items 中,然后在完全处理请求后立即处置。

在Aplication_EndRequest事件中,我调用RepositoryContext的Terminate()方法,该方法将从 HttpContext.Current.Items 集合中找到活动的 ObjectContext ,并调用在其连接上关闭()并在其上 Dispose()

问题在于,有时候我的某个页面会出现奇怪的行为。在某些情况下,我得到一个错误说:

  

ObjectContext实例已被释放,不能再用于需要连接的操作

我认为可能会发生这种情况,因为不仅页面请求在完成后调用Application_EndRequest事件而且还会调用图像请求等等,因此有时其他请求可能会在完成其工作之前处理主页面请求ObjectContext,但这不应该发生,因为所有内容都是在集合 HttpContext.Current.Items 上进行的,当然不是在HTTP请求之间共享。

此外,研究可能是由于某些数据库请求的延迟加载引起的,但这不应该是这种情况,因为我不会在代码上调用Dispose(我已检查过),因此Dispose()on只有当一切完成时才应该调用EndRequest,不应该吗?

关于可能导致此问题的任何想法?我该怎么测试呢?你会建议什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

这意味着已经在ObjectContext上调用了Dispose()。关于为什么会发生这种情况有很多不同的原因,但它归结为在Application_EndRequest之前调用Dispose()的事实。没有所有来源,就不可能确切地说出原因。

因为您要求建议,我的第一个是从HttpContext中取出ObjectContext。数据库连接应该只存在很短的时间,并执行特定的任务。如果它是短暂的,您可以将ObjectContext放在using语句中,该语句将自动为您调用Dispose()。

答案 1 :(得分:1)

假设您有一个为您提供当前ObjectContext的类,那么程序员可能会根据博客中的一些示例或类似内容编写此代码:

using(var context = ContextProvider.GetCurrentContext()){
    ...
}

并在请求结束前处理了ObjectContext。

如果要测试ObjectContext的处置位置,可以执行以下操作:

在ObjectContext实现中,将Dispose方法更改为:

public override void Dispose() {
    throw new InvalidOpearationException("Gotcha!");
}

public void ActuallyDisposePlease() {
    base.Dispose();
}

在Application_EndRequest中调用ActuallyDisposePlease()方法。

OF COURSE,这是用于测试/调试/诊断的角度,永远不应该达到生产。