Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need way to disable disposing of DbContext when root DbContextScope is disposed #51

Closed
riley-van-hengstum opened this issue May 9, 2017 · 3 comments

Comments

@riley-van-hengstum
Copy link

riley-van-hengstum commented May 9, 2017

The way this library works now is that the DbContext instances are disposed when the root DbContextScope is disposed.

I'm using this library in an OData Web Api project. The behaviour of disposing DbContext instances is causing problems with the OData pipeline because OData expects the DbContext to be open until very late in the Web Api pipeline. The only way of keeping the DbContext open is to create the DbContextScope very early in the process in the Owin middleware, but I didn't want to do that because I want to have a readonly or readwrite scope depending on the requested controller action, and this is not yet known at the Owin stage.

So I had to resort to trickery to keep the DbContext from being disposed right away, which was to override the Dispose(bool disposing) method of the DbContext and add another ManualDispose() method to dispose of the DbContext at a later time.

It would be nice if it were possible to create a DbContextScope with the option to disable auto disposing of the DbContext instances.

Or does someone have another suggestion to tackle this issue?

@crush83
Copy link

crush83 commented Oct 25, 2017

Can you just not dispose the DbContextScope?

@rock-walker
Copy link

rock-walker commented Dec 19, 2017

Jaap-van-Hengstum, please, share your decision, if your figured it out. I'm really on the same page with about this question.
I play with .NET Core and native DI for my Web API. Tried many approches with DbContextScope , IAmbientContextLocator and their lifetimes. As I understood correctly, DbContextScope should be Transient and AmbientContextLocator - Singleton. But the problem exactly the same - DbContextScope kills DbContext everytime.

@rock-walker
Copy link

In short words, the answer is: register your DbContext as Transient lifetime.

And ... the long story:
In .NET Core 1.1 you register your DbContexts by default in Scoped lifetime, like this:
services.AddDbContext<AttendeeContext>(options => options.UseSqlServer(connectionString)

So, how DbContextScope does his job (as long, as I debugged sources):

  1. in each new scope, (like it usually recommends: using (var dbScope = _factory.Create()) { ... } ) the new collection of DbContexts initialized - not previously initialized DbContexts in the current scope of whole web request.
  2. when the dbScope code block ends, using statement calls Dispose for your DbContextScope and that means exact disposing of all your existing collection of DbContexts.
  3. What does it mean for lifetime of DbContext in scope of lifetime of whole Web request?
    -- it means, that you manually have killed DbContext somewhere in the middle of living your Web request, and DbContext becomes unavailable for next calls inside still alive Web Request.

The solution is to allow your serviceProvider to recreate DbContext for each request during Scoped lifetime of your Web request:
services.AddDbContext<AttendeeContext>(options => options.UseSqlServer(connectionString, ServiceLifeTime.Transient)
And by the way, I also registered IDbContextScopeFactory as Singleton lifetime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants