gpt4 book ai didi

c# - 我应该如何在 MVC Core 中管理 DbContext 生命周期?

转载 作者:可可西里 更新时间:2023-11-01 02:59:25 26 4
gpt4 key购买 nike

来自Documentation

Entity Framework contexts should be added to the services container using the Scoped lifetime. This is taken care of automatically if you use the helper methods as shown above. Repositories that will make use of Entity Framework should use the same lifetime.

我一直认为,我应该为我必须处理的每个工作单元创建一个新的 Context。这让我想到,如果我有一个 ServiceAServiceB,它们在 DbContext 上应用不同的操作,它们应该获得不同的实例DbContext.

documentation内容如下:

  • Transient objects are always different; a new instance is provided to every controller and every service.

  • Scoped objects are the same within a request, but different across different request

回到ServiceAServiceB,在我看来,Transient更合适。

我研究过,上下文应该只在每个 HttpRequest 中保存一次,但我真的不明白这是如何工作的。

特别是如果我们看一下一项服务:

using (var transaction = dbContext.Database.BeginTransaction())
{
//Create some entity
var someEntity = new SomeEntity();
dbContext.SomeEntity.Add(someEntity);

//Save in order to get the the id of the entity
dbContext.SaveChanges();

//Create related entity
var relatedEntity = new RelatedEntity
{
SomeEntityId = someEntity.Id
};
dbContext.RelatedEntity.Add(relatedEntity)
dbContext.SaveChanges();
transaction.Commit();
}

这里我们需要保存上下文以获取与我们刚刚创建的另一个实体相关的实体的 ID。

同时另一个服务可以更新相同的上下文。据我所知,DbContext 不是线程安全的。

在这种情况下我应该使用 Transient 吗?为什么文档建议我应该使用Scoped

我是否遗漏了框架的某些重要部分?

最佳答案

正如其他人已经解释过的,您应该对数据库上下文使用范围依赖,以确保它能被正确重用。对于并发性,请记住您也可以异步查询数据库,因此您可能不需要实际的线程。

如果您确实需要线程,即后台 worker ,那么它们的生命周期可能与请求的生命周期不同。因此,那些线程应该使用从请求范围检索到的依赖项。当请求结束并且其依赖范围正在关闭时,一次性依赖将被妥善处理。对于其他线程,这意味着它们的依赖项可能最终会被处理掉,尽管它们仍然需要它们:坏主意。

相反,您应该为您创建的每个线程显式打开一个新的依赖范围。您可以通过注入(inject) IServiceScopeFactory 来做到这一点并使用 CreateScope 创建范围.结果对象将包含一个服务提供者,您可以从中检索您的依赖项。由于这是一个单独的作用域,因此将在该作用域的生命周期内重新创建作用域依赖关系(如数据库上下文)。

为了避免进入服务定位器模式,您应该考虑让您的线程执行一个中央服务,该服务汇集了所有必要的依赖项。然后线程可以这样做:

using (var scope = _scopeFactory.CreateScope())
{
var service = scope.ServiceProvider.GetService<BackgroundThreadService>();
service.Run();
}

BackgroundThreadService 及其所有依赖项都可以按照常见的依赖注入(inject)方式接收依赖项。

关于c# - 我应该如何在 MVC Core 中管理 DbContext 生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46412734/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com