次のコードのようなもので実装された作業単位パターンを見てきました。
private HashSet<object> _newEntities = new HashSet<object>();
private HashSet<object> _updatedEntities = new HashSet<object>();
private HashSet<object> _deletedEntities = new HashSet<object>();
そして、これらの各 HashSet にエンティティを追加するメソッドがあります。
コミット時に、UnitOfWork はエンティティごとにいくつかの Mapper インスタンスを作成し、架空の Mapper から Insert、Update、Delete メソッドを呼び出します。
このアプローチの問題点は、Insert、Update、Delete メソッドの名前がハードコードされているため、そのような UnitOfWork は単純な CRUD 操作しかできないように見えることです。しかし、次の使用法が必要な場合はどうでしょうか。
UnitOfWork ouw = new UnitOfWork();
uow.Start();
ARepository arep = new ARepository();
BRepository brep = new BRepository();
arep.DoSomeNonSimpleUpdateHere();
brep.DoSomeNonSimpleDeleteHere();
uow.Commit();
3 つの HashSet アプローチは失敗します。これは、挿入、更新、削除操作に対してのみ A エンティティと B エンティティを登録できたからですが、これらのカスタム操作が必要になりました。
したがって、常にリポジトリ操作をスタックしてから、すべてを実行できるとは限らないようですUnitOfWork.Commit();
この問題を解決するには?最初のアイデアは、メソッドのアドレスを保存できることです
arep.DoSomeNonSimpleUpdateHere();
brep.DoSomeNonSimpleDeleteHere();
UoWインスタンスでそれらを実行しますuow.Commit()
が、すべてのメソッドパラメーターも保存する必要があります. それは複雑に聞こえます。
もう 1 つのアイデアは、リポジトリを完全に UoW 対応DoSomeNonSimpleUpdateHere
にすることです。実行中の UoW があることを検出できるので、実行せずDoSomeNonSimpleUpdateHere
に操作パラメータと「保留中」ステータスをリポジトリ インスタンスのスタックに保存します (明らかに保存できません)。 UoW は具体的なリポジトリの実装に依存するべきではないため、UoW のすべて)。そして、関連するリポジトリを UoW インスタンスに登録します。UoW が を呼び出すとCommit
、トランザクションが開かれ、保留中のリポジトリごとに Flush() のようなものが呼び出されます。現在、Repository のすべてのメソッドには、UoW の検出と後で操作を延期するためのいくつかの要素が必要Commit()
です。
簡単な質問は、保留中のすべての変更を UoW の複数のリポジトリに登録し、Commit()
それらすべてを 1 つのトランザクションで登録する最も簡単な方法は何ですか?