以下描述,仅代表个人看法,如果有不同看法欢迎讨论
在开发过程中EF是一个使用率较高ORM框架,但是对于刚接触的人来说需要知道的一点就是EF中的数据上下文(DBContext)是非线程安全的。
非线程安全的意思是:当有并发情况时(多个线程操作同一个DBContext),此对象会引发异常
如此说来就会产生一个问题需要我们思考:如何管理DBContext实例?
就问题所引发的异常来看,只需将DBContext实例按照线程划分,即每个线程只使用一个DBContext实例,就能解决线程安全问题
1.在.Net Framework中,可以使用CallContext对象来管理线程中的DBContext,一个线程存一个DBContext对象,直接上菜
private static DbContext GetDbContext()
{
DbContext _context = CallContext.GetData(“dbContext”) as DbContext;
if (_context == null)
{
_context = new MyDbContext();
CallContext.SetData(“dbContext”, _context);
}
return _context;
}
如果想要重新获取DBContext对象,可以 CallContext.SetData(“dbContext”, null);
这种获取DBContext对象的方式,可以满足在同一个请求中使用多线程检索数据内容
2.在.Net Core中没有直接提供CallContext对象,但是好像也有人构造了,需要的可以去搜搜。这里提供的方法并不是线程内唯一,是框架提供的DBContext注入方法,默认一个请求内唯一
services.AddDbContext(option =>
{
option.UseSqlServer(connectionString);
});
使用上述方法在一次请求中如果使用多线程请求DBContext,有可能引发线程安全异常,如果需要在一个请求管道中使用多线程,那么还是建议在Repository层使用如下方法安全些
using(DbContext context=new DbContext){
}
以上方法只是个人开发中的一些方案总结,仅供参考,欢迎讨论!