简体   繁体   中英

Correct pattern for DbContext use in MVC/EF6/WebApi2 application

I'm hoping to finally get to the very bottom of an ongoing problem with Entity Framework DbContexts. The history of my problem is that sporadically - especially when requests come in in fast succession - my DbContext throws a variety of strange errors, including the following:

System.InvalidOperationException : There is already an open DataReader associated with this Command which must be closed first.

System.InvalidOperationException : Internal connection fatal error.

My MVC code is based around a basic pattern where I have a base controller, which looks like this:

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

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

All other controllers derive from this base controller, thereby making the DbContext available as necessary to controller actions, none of which are asynchronous. The only exception is my custom authorization, which also creates a DbContext upon access and is called with virtually every controller action (via attribute):

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);
    }
}

I've also experimented with the following to no avail:

  • Removed all asynchronicity from my controller actions
  • Removed lazy loading from DbContext and inserted explicit Include statements with each call

Looking through StackOverflow, other people appear to have had similar issues:

Neither answers really helped me get to the bottom of the problem, but the OP-answer of the second SO post said ("After further investigation I found out that request processing thread sometimes steals DbContext from other thread") , but I'm not sure how this really applies.

Is there something fundamentally wrong with my design? Wrapping each controller action's DbContext into a using block can't be right, even though this blog says it is - but doesn't that cause other problems, such as returning objects that are no longer attached to a DbContext (and therefore lose change tracking)...?

when requests come in in fast succession

Made me think about aa problem about a year ago so I don't think it related to EF6. However, it took me quite some time to figure it out.

Allow your databse to have more than one pending request per application. Change your connection string to MultipleActiveResultSets=True

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM