私はリポジトリでDbContextを取得するためにDbContextFactoryを使用したとしましょう。 (私はそれが最善の解決策ではないと思います)。DbContextの処理、dbcontextファクトリ、作業ユニット
public class DbContextFactory : Disposable, IDbContextFactory
{
private readonly Dictionary<Type, System.Data.Entity.DbContext> _dbContexts;
public DbContextFactory()
{
_dbContexts = new Dictionary<Type, System.Data.Entity.DbContext>();
}
public T GetDbContext<T>() where T : System.Data.Entity.DbContext, new()
{
if (!_dbContexts.ContainsKey(typeof(T)))
{
_dbContexts.Add(typeof(T), new T());
}
return _dbContexts[typeof(T)] as T;
}
protected override void DisposeCore()
{
foreach (var kvpDbContext in _dbContexts)
{
kvpDbContext.Value?.Dispose();
}
}
}
そして、私は私がリポジトリメソッドを呼び出すよりも、ビジネスロジッククラス
public class UnitOfWork<T> : IUnitOfWork
where T : System.Data.Entity.DbContext, new()
{
private readonly IDbContextFactory _dbContextFactory;
private T _dbContext;
public UnitOfWork(IDbContextFactory dbContextFactory)
{
_dbContextFactory = dbContextFactory;
}
public T DbContext => _dbContext ?? (_dbContext = _dbContextFactory.GetDbContext<T>());
public void Commit()
{
DbContext.SaveChanges();
}
}
に注入し、そして者はそれを言わせたUnitOfWorkを持っているが、例外がスローされます。私はコールした場合起こった何
public void CreateUser(User user)
{
_userRepository.Add(user);
throw new Exception();
UnitOfWork.Commit();
}
同じリクエスト内の他のリポジトリメソッド(または単にリクエストごとのインスタンスとしてfactoryを使用しない)、そのメソッドは正常に終了し、UnitOfWork.Commit()が呼び出され、失敗したCreateUserメソッドで作成されたものも保存されますか?または接続を閉じる例外をスローした直後で、そのメソッドからの変更が保存される危険はありませんか?
もっと明確にするには: 私はWCFサービスでそれをホストしたいと思います。シングルトンモードで言うとします。 次に、複数の(例えば5つの)リポジトリ呼び出しを含む1つの要求呼び出しメソッドと最初の3つは成功し、4番目の呼び出しは失敗します。つまり、UnitOfWork.Commit()を呼び出しません。 そして、他のリクエストが来て、それはちょうど成功です。以前のメソッドからの最初の3つのリポジトリからの変更が保存されることを意味しますか? シングルトンのため、同じDbContextFactoryに同じDbContextが存在します。
それはその例外と何が起こるかによって異なります。あなたがそれを処理しなければ、ユーザーは500のエラーを受け取ります(私はこれがasp.netであるとみなします)。これを処理してもリクエストが続行されると、同じdbcontextインスタンス上のsavechangesの次の呼び出しで同じ例外が生成されます。 – Igor
私はより明確にするために投稿を編集しました。 – JeloneK
@JeloneK 'DbContext'は* Unit Of Work *パターンの実装です。あなたがしたように、別の作業単位に再度ラップするのはあまり意味がありません。その追加ラッパーは目的を果たさない。 – Kostya