Mic*_*zyk 1 dependency-injection dbcontext asp.net-core
I've configured my DbContext with services.AddDbContext() in the Startup class and constructor injection in my controllers works very well.
默认情况下,它是一个范围服务,但我在应用程序中有一个地方,我想在单独的工作范围内更新实体的单个属性。所以我需要在控制器中创建一个新的 DbContext,但我不确定如何。我希望它由 DI 创建,因此我不必手动调用构造函数并提供所需的所有选项。有没有办法做到这一点?也许有办法从 DI 获取数据库上下文选项?然后我可以轻松构建 DbContext。
将 DbContext 注入控制器的正常方法可以正常工作,只要您在 HTTP 请求期间执行合理的工作量即可。但是,如果您正在运行后台/并行操作,或者如果您正在查询和修改大量记录(导致SaveChangesAsync()由于DbContext.ChangeTracker跟踪大量对象而陷入困境),您可能想要创建 DbContext 。如果是这样,您可以为每个操作创建一个作用域 DbContext。这是一个示例 ASP.NET Core 控制器方法:
/// <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();
}
Run Code Online (Sandbox Code Playgroud)
此外,我建议在 Startup.cs 中从 切换AddDbContext()到AddDbContextPool()以避免为每个请求创建/销毁 DbContext 对象。DbContextPool 将在 DbContext 对象超出范围后将其重置为干净状态。(如果您感兴趣,DbContextPool 会调用DbContext.ResetState()和DbContext.Resurrect(),但我不建议直接从您的代码中调用它们,因为它们可能会在未来版本中发生变化。)
https://github.com/aspnet/EntityFrameworkCore/blob/v2。 2.1/src/EFCore/Internal/DbContextPool.cs#L157
| 归档时间: |
|
| 查看次数: |
4902 次 |
| 最近记录: |