I am trying to upgrade our current .Net Core application from 1.1 to 2.0 and am getting this runtime error: \"The DbContext of type \'CoreContext\' cannot be pooled because
This issue is mostly encountered when you "Scaffold-Dbcontext" and two constructors are generated.
Simple Solutions:
AddDbContextPool: If you want to use AddDbContextPool, remove your empty constructor and maintain the one with the DbContextOptionsBuilder. Note that in this case you might have to provide the options, as suggested in the previous posts.
AddDbContext: With AddDbContext, you can have both constructors/Overloads
Note: AddDbContextPool is preferred for performance reasons!
Try to use AddDbContext
instead of AddDbContextPool
. This helped me in the same situation.
services.AddDbContext<CoreContext>(options => options.UseSqlServer(absConnectionString));
When using DbContext Pooling
, your own state (e.g. private fields) in your derived DbContext class will be preserved. Which means the lifetime of your services is now singleton
. That's why you shouldn't have other injected services here.
But it's possible to query the required services this way:
First we should use the UseInternalServiceProvider
method on DbContextOptionsBuilder
to tell EF which service provider to use for its services. This service provider must have all the services configured for EF and any providers. So we should register EF Services manually:
services.AddEntityFrameworkSqlServer();
And then introduce the application's services provider which now includes the EF Services too:
services.AddDbContextPool<ApplicationDbContext>((serviceProvider, optionsBuilder) =>
{
optionsBuilder.UseSqlServer("...");
optionsBuilder.UseInternalServiceProvider(serviceProvider);
});
After that define these namespaces:
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
And now you can access the registered services in the application within the ApplicationDbContext class using the following methods
var siteSettings = this.GetService<IOptionsSnapshot<SiteSettings>>();
Or
var siteSettings = this.GetInfrastructure().GetRequiredService<IOptionsSnapshot<SiteSettings>>();
this
is the current instance of the DbContext.
Remove the default constructor in the DbContext class, this worked for me
"because it does not have a single public constructor accepting a single parameter of type DbContextOptions"
If you have any public constructors apart from one that accepts DbContextOptions, you need to remove them or make them non-public in order to use context pooling.
Also, there are restrictions on what can be done by overriding the OnConfiguring method. This is referenced in the documentation here but it isn't explicit about what those restrictions are: https://docs.microsoft.com/en-us/ef/core/what-is-new/index#dbcontext-pooling