このようなシナリオでは、ここで説明する新しい最新のアプローチが推奨されます。
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();
}
}
内では、スコープが管理するインスタンスに 2 つの方法でDbContextScopeアクセスできます。次のようにプロパティ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);
}
}