2017-10-28 19 views
1

私はリポジトリで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が存在します。

+0

それはその例外と何が起こるかによって異なります。あなたがそれを処理しなければ、ユーザーは500のエラーを受け取ります(私はこれがasp.netであるとみなします)。これを処理してもリクエストが続行されると、同じdbcontextインスタンス上のsavechangesの次の呼び出しで同じ例外が生成されます。 – Igor

+0

私はより明確にするために投稿を編集しました。 – JeloneK

+1

@JeloneK 'DbContext'は* Unit Of Work *パターンの実装です。あなたがしたように、別の作業単位に再度ラップするのはあまり意味がありません。その追加ラッパーは目的を果たさない。 – Kostya

答えて

-1

@Igorは、あなたが処理したかどうかにかかわらず、例外を処理するかどうかには違いがありますが、同じリクエストでanothetリポジトリを呼び出す必要があるため、処理したと仮定します。

DbContextFactoryの同じインスタンスを再利用し、それはDbContextインスタンスを保持する人物だと言っていたように、その工場を別の場所に配置しない限り、コンテキストには同じUserインスタンスが追加されますそのため、anothetリポジトリの同じコンテキストでCommitを呼び出すと、依然としてそのユーザーが挿入されます。