在这种情况下,建议采用此处阐述的新现代方法。
如果您熟悉TransactionScope
该类,那么您已经知道如何使用DbContextScope
. 它们在本质上非常相似——唯一的区别是DbContextScope
创建和管理DbContext
实例而不是数据库事务。但就像TransactionScope
,DbContextScope
是环境的,可以嵌套,可以禁用其嵌套行为并且可以在异步执行流中正常工作。
public void MarkUserAsPremium(Guid userId)
{
using (var dbContextScope = _dbContextScopeFactory.Create())
{
var user = _userRepository.Get(userId);
user.IsPremiumUser = true;
dbContextScope.SaveChanges();
}
}
在 aDbContextScope
中,您可以通过DbContext
两种方式访问范围管理的实例。您可以通过以下DbContextScope.DbContexts
属性获取它们:
public void SomeServiceMethod(Guid userId)
{
using (var dbContextScope = _dbContextScopeFactory.Create())
{
var user = dbContextScope.DbContexts.Get<MyDbContext>.Set<User>.Find(userId);
[...]
dbContextScope.SaveChanges();
}
}
但这当然只在创建DbContextScope
. 如果您需要DbContext
在其他任何地方访问环境实例(例如,在存储库类中),您可以只依赖于IAmbientDbContextLocator
,您可以像这样使用它:
public class UserRepository : IUserRepository
{
private readonly IAmbientDbContextLocator _contextLocator;
public UserRepository(IAmbientDbContextLocator contextLocator)
{
if (contextLocator == null) throw new ArgumentNullException("contextLocator");
_contextLocator = contextLocator;
}
public User Get(Guid userId)
{
return _contextLocator.Get<MyDbContext>.Set<User>().Find(userId);
}
}