Two (almost) concurrent DbContexts causing problems: How to share between Controller and AuthorizeAttribute

asp.net-mvc-5 concurrency dbcontext entity-framework entity-framework-6

Question

Every once in a while, I'm encountering the following exception in my ASP.NET/MVC5/WebAPI2/EF6/MSSQL application:

System.InvalidOperationException: The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.

I've traced this to my authorization code, which is a derivative of AuthorizeAttribute and instantiating its own DbContext to verify that my Web API consumer's API key is valid (the error occurs when trying to access the database).

The AuthorizeAttribute in turn decorates controllers which are derivatives of my BaseController, which also instantiates a DbContext for controller work.

After trying to troubleshoot this for days and reading this and this I suspect that creating the two DbContext instances per request is the problem. However, I'm not quite sure how I can use only a single instance for this work. My controller code currently nicely instantiates the DbContext upon its own creation and disposes of it transparently when the controller itself disposes. The AuthorizeAttribute is completely independent from all this and creates the context on demand for its own purposes.

Any patterns/ideas how to preserve/reuse the same DbContext for both units of work?

Accepted Answer

I had exactly the same issue when starting out with a base application using Entity Framework 6 for the first time.

The best solution for me was to ensure only one DbContext instance during the request life cycle using Autofac (with MVC integration) and Autofac's InstancePerRequest lifetime scope.

If you're interested in going down the dependency injection route (which I'd strongly advise) I would recommend familiarizing yourself with Autofac - and for more information on your particular issue check out davidbitton's answer here - it will get you on the right track.




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why