从Documentation我应该如何管理MVC Core中的DbContext生命周期?
实体框架上下文应该被添加到使用
Scoped
终身服务容器 。如果您使用如上所示的帮助程序方法,则会自动执行此操作。使用实体框架 的存储库应该使用相同的生命周期。
我一直认为,我应该为每一个单位的工作单位创造一个新的环境,我必须处理。这让我想,如果我有一个ServiceA
和ServiceB
,它们在DbContext
上应用不同的操作,它们应得到不同的实例DbContext
。
的documentation读取如下:
Transient
对象总是不同;为每个控制器和每个服务提供一个新实例。
Scoped
对象是请求中的相同,但不同的跨越不同的要求
再回到ServiceA
和ServiceB
,它的声音对我来说,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
?
我错过框架的一些重要部分吗?
切勿使用临时'DbContext'注册。瞬态生命周期将创建一个服务的新实例**每个**它是另一个服务请求的时间。这将导致每个请求有多个'DbContext's。在同一请求中重复使用相同的'DbContext'实例没有问题:每个请求都绑定到单个线程,所以根本没有线程安全问题。 –
但是如果服务因为某种原因(例如Task.Start)并行处理会发生什么? @FedericoDipuma –
你的意思是*并行*?你是否明确地产生了一个新的线程,你可以使用相同的'DbContext'? –