我正在 Azure 函数应用程序中使用实体框架,我得到了一个初始化数据库模型的
DbContext
类。还有一个名为 DbManage
的类,它使用 DbContext 在数据库上执行实际所需的操作。
到目前为止,
DbManage
类的实现有这样的方法:
public bool SomeAction(string input, MyContext dbContext = null)
{
if (dbContext == null)
{
dbContext = new MyContext();
}
using (dbContext)
{
// ....
}
}
当单元/集成测试调用这些方法时,模拟对象会传递给这些方法,而真实代码会传递 null,这使得上下文每次都会实例化。
问题是,每次我想像上面的代码那样与数据库进行会话时,是否应该重新实例化数据库上下文类,或者是否可以将同一对象用于所有调用?如果可以使用同一个对象并使用 DI 注入它,它应该获得什么类型的生命周期(单例/作用域/瞬态)?
来自 https://learn.microsoft.com/en-us/ef/core/dbcontext-configuration/ :
当并发访问未被检测到时,可能会导致未定义的情况 行为、应用程序崩溃和数据损坏。
任何显式并行执行多个线程的代码都应该 确保 DbContext 实例不会同时访问。
使用依赖注入,这可以通过注册来实现 上下文作为作用域,并创建作用域(使用 IServiceScopeFactory)为每个线程,或通过注册 DbContext 作为瞬态(使用 AddDbContext 的重载,它需要一个 ServiceLifetime 参数)。