このようなシナリオでは、ここで説明する新しい最新のアプローチが推奨されます。
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);
}
}