在MVC / EF6 / WebApi2应用程序中使用DbContext的正确模式

时间:2014-01-20 08:06:28

标签: c# design-patterns asp.net-web-api asp.net-mvc-5 dbcontext

我希望最终能够解决Entity Framework DbContexts持续存在的问题。我的问题的历史是零星的 - 特别是当请求快速连续进入时 - 我的DbContext抛出了各种奇怪的错误,包括以下内容:

  

System.InvalidOperationException :已经有一个与此命令关联的打开的DataReader,必须先关闭它。

     

System.InvalidOperationException :内部连接致命错误。

我的MVC代码基于一个基本模式,我有一个基本控制器,如下所示:

public class BaseController : Controller
{
    protected readonly DbContext db = new DbContext();

    protected override void Dispose(bool Disposing)
    {
         db.Dispose();
         base.Dispose(disposing);
    }
}

所有其他控制器都派生自此基本控制器,从而使DbContext可用于控制器操作,其中任何一个都不是异步的。唯一的例外是我的自定义授权,在访问时创建DbContext,并且几乎每个控制器操作都被调用(通过属性):

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    private DbContext db;

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
         db = new DbContext();
         var user = 
             db.Security.FirstOrDefault(u => 
                u.Id == actionContext.ControllerContext.Request.Headers.First(h => 
                h.Key == "Id").Value);

         return (user != null);
    }
}

我也试过以下无济于事:

  • 从我的控制器操作中删除了所有异步性
  • 从DbContext中删除延迟加载,并在每次调用时插入显式Include语句

通过StackOverflow,其他人似乎遇到了类似的问题:

这两个答案都没有真正帮助我解决问题的根源,但第二个SO帖子的OP答案说(“经过进一步调查后我发现请求处理线程有时从其他线程窃取DbContext”) ,但我不确定这是如何实现的。

我的设计是否存在根本性的问题?将每个控制器操作的DbContext包装到使用块中可能不正确,即使this blog表示它是 - 但不会导致其他问题,例如返回不再存在的对象附加到DbContext(因此失去更改跟踪)......?

1 个答案:

答案 0 :(得分:0)

  

当请求快速连续进入时

让我想起一年前的一个问题所以我认为它与EF6无关。然而,我花了很长时间才弄明白。

允许您的数据库每个应用程序有多个待处理请求。将您的连接字符串更改为 MultipleActiveResultSets=True