The normal method of injecting a DbContext into your Controller works fine, as long as you are doing a reasonable amount of work during an HTTP request. However, you might want to create a DbContext if you are running a background/parallel operation, or if you are querying and modifying a lot of records (causing SaveChangesAsync() to get bogged down because DbContext.ChangeTracker is tracking a lot of objects). If so, you can create a scoped DbContext for each operation. Here is an example ASP.NET Core Controller method:
/// <summary>
/// An endpoint that processes a batch of records.
/// </summary>
/// <param name="provider">The service provider to create scoped DbContexts.
/// This is injected by DI per the FromServices attribute.</param>
/// <param name="records">The batch of records.</param>
public async Task<IActionResult> PostRecords(
[FromServices] IServiceProvider provider,
Record[] records)
{
// The service scope factory is used to create a scope per iteration
var serviceScopeFactory =
provider.GetRequiredService<IServiceScopeFactory>();
foreach (var record in records)
{
// At the end of the using block, scope.Dispose() will be called,
// releasing the DbContext so it can be disposed/reset.
using (var scope = serviceScopeFactory.CreateScope())
{
var context = scope.ServiceProvider.GetService<MainDbContext>();
// Query and modify database records as needed
await context.SaveChangesAsync();
}
}
return Ok();
}
Also, I would recommend switching from AddDbContext() to AddDbContextPool() in Startup.cs to avoid creating/destroying DbContext objects for each request. The DbContextPool will reset the DbContext objects to a clean state after they go out of scope. (In case you were interested, DbContextPool calls DbContext.ResetState() and DbContext.Resurrect(), but I wouldn't recommend calling those directly from your code, as they will probably change in future releases.)
https://github.com/aspnet/EntityFrameworkCore/blob/v2.2.1/src/EFCore/Internal/DbContextPool.cs#L157
DbContextOptionsfrom DI and then create a new DbContext with it. - Brad