For Asp.net Core apps, which one do we have to use? AddDbContext
or AddDbContextPool
? According to EF Core documentation, AddDbContextPool
provides high performance but the default Asp.net Core project templates use AddDbContext
.

- 14,188
- 21
- 90
- 165
-
12Unless you have needs for high performance, you won't need `AddDbContextPool`. High-performance means 2000-5000 requests (per machine you are running your apps on) per second. 100 requests / min is no high performance and you are good with the defaults – Tseng Jan 25 '18 at 14:32
-
1@Tseng How about practically? - @Gabriel's answer mentions having to create new `DbContext` for parallel queries - will `AddDbContextPool` be simpler since it does this automatically? Any downsides? – Jeppe Aug 08 '19 at 08:32
-
@Jeppe I'm a little late, but pooling won't help you at all with parallel queries. Whether you use pooling or not, you're still only given one `DbContext` per scope from dependency injection. – Gabriel Luci Aug 19 '20 at 09:51
1 Answers
The answer is here (under "DbContext pooling"): https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#dbcontext-pooling
DbContext
is not thread-safe. So you cannot reuse the same DbContext
object for multiple queries at the same time (weird things happen). The usual solution for this has been to just create a new DbContext
object each time you need one. That's what AddDbContext
does.
However, there is nothing wrong with reusing a DbContext
object after a previous query has already completed. That's what AddDbContextPool
does. It keeps multiple DbContext
objects alive and gives you an unused one rather than creating a new one each time.
Which one you use is up to you. Both will work. Pooling has some performance gains. However the documentation warns that if you use any private properties in your DbContext
class that should not be shared between queries, then you should not use it. I imagine that's pretty rare though, so pooling should be appropriate in most cases.

- 38,328
- 4
- 55
- 84
-
3But, and what about sql transations? if transations scope is per connection, in the pool of connection is could be affected? – Alexsandro Feb 07 '19 at 17:52
-
The [default transaction behavior](https://learn.microsoft.com/en-us/ef/core/saving/transactions#default-transaction-behavior) is that it creates a transaction for each call to `SaveChanges()` and closes it automatically. So it only *might* be an issue if you create a transaction manually and don't close it off. – Gabriel Luci Feb 07 '19 at 19:17
-
4Will returned DbContext keep their underlying connection alive whilst being pooled? I can't seem to find any clue in the docs. – René Schindhelm Apr 30 '19 at 21:26
-
@GabrielLuci if I use this within the context of a scoped repository and set a public property (or a private property via a method) in the constructor of that repository, it should be OK because that dbcontext will have whatever property I've updated reset before each use.. right? – djsoteric Feb 17 '20 at 22:45
-
-
@GabrielLuci Sorry, I mean if I only use the DbContext within one scoped class (scoped is recommended for generic repositories), and in the constructor of that class, I set some property on the DbContext to whatever I need for this request so that I'm 100% certain that property is persisted throughout the request scope.. I shouldn't run into any issues, right? I just want to make sure I'm not missing anything. The warning about not using this if you use some private property should only apply for readonly properties which can only be set once in the constructor is what I'm presuming. – djsoteric Feb 18 '20 at 10:36
-
@djsoteric *"should only apply for readonly properties"* - Why do you say that? Pooling reuses the same instance of the class. If you add your own property (readonly or otherwise), how would Entity Framework even be aware that property exists and know that it needs to be reset before reusing the object? – Gabriel Luci Feb 18 '20 at 13:45
-
I'm not relying on EF to reset it. I'm saying that the *only* place my app will use the DbContext is in one repository that is scoped (reset for each request) where I will update that property in the constructor of the repository. – djsoteric Feb 18 '20 at 17:38
-
1@djsoteric If you are handling the resetting of that property, then yes, you will be fine as long as you are resetting it properly when needed. – Gabriel Luci Feb 18 '20 at 17:53
-
@RenéSchindhelm `AddDbContextPool` enables pooling for the `DbContext`, not for the underlying `DbConnection`. When the `DbContext` runs out of scope, the connection is closed and the context is returned to the pool. Most providers however support *connection* pooling as well. If both, context and connection pooling are enabled, the connection that gets closed by the context that ran out of scope not actually gets closed, but is returned to the connection pool. If you call `AddDbContextPool` afterwards, an existing context gets reused that, when opened, reused an existing connection. – lauxjpn Apr 16 '20 at 12:13
-
13Internals: When a `DbContext` is returned to the context pool, the state of the context is being reset by calling its `IResettableService.ResetState()` method. This method in turn calls the `GetResettableServices()` method and then calls `IResettableService.ResetState()` on the returned objects as well. One of those objects is the EF Core providers `RelationalConnection` derived object, because it implements `IResettableService` as well. The default implementation of `ResetState()` in `RelationalConnection` is to call its own `Dispose()` method, which in turn calls `DbConnection.Dispose()`. – lauxjpn Apr 16 '20 at 12:31