web-dev-qa-db-ja.com

リポジトリパターンで本当に必要な作業単位パターン

プロジェクトでEF6を使用しようとしています。私はちょうど C#とエンティティフレームワークを使用したリポジトリパターン、正しく完了| Mosh ビデオを見ました。リポジトリの必要性は理解していますが、UnitOfWorkはまだ理解していません。 UnitOfWorkの代わりに使用するDBContextがすでにあります。ビデオのサンプルコードでは次のようになります:

using(var UnitOfWork = new UnitOfWork(new DBContext()))
{
    UnitOfWork.Courses.Get(1);
}

これのメリットがわかりません。すべてのリポジトリでdbContextを直接使用できます。

using(var dbContext = new DBContext())
{
    var courseRepo = new CourseRepo(dbContext);
    var otherRepo = new OtherRepo(dbContext);

    courseRepo.Get(1);
}

したがって、私のリポジトリは同じdbContextを使用します。 UnitOfWorkの理由は何ですか?

1
Mansur

エンティティフレームワークDbContextis作業単位とそのDbSet<T>プロパティareリポジトリ。
それはあなたがそれらの上にあなた自身の層を決して転がすべきではないということではありませんが、あなたがそれを使用している方法で、dbコンテキストがユニットの主な目標を排除することを主張することは正しいです仕事の。

手動でコンテキストをリポジトリに挿入するという点で非常にユニークな状況です。これにより、リポジトリ(リポジトリのコンシューマー、つまりusingブロックを含むクラス)がコンテキストといつコミットされるかを直接制御できます。

これは、リポジトリがEFの依存関係を隠すため、リポジトリの外部でコンテキストを使用できないため、他の多くのコードベースには当てはまりません。これにより、リポジトリの上のレイヤーのコンテキストを制御できなくなり、複数のリポジトリにまたがるトランザクションを指示することが難しくなります。

このような場合、カスタムで作成された作業ユニットは、作業ユニットを介してコンシューマにdbコンテキストを間接的に制御させるため、理にかなっています。

つまり、Entity Frameworkのコンテキストでは、作業ユニットは、EFコンテキストの上にあるEFに依存しないインターフェースとしてのみ使用する必要があります。


要約すると、私はあなたの実際の質問と、あなたが実際に尋ねていたと思う質問に対処したいと思います。

作業単位パターンは本当にリポジトリパターンで必要ですか?

はい、複数のリポジトリにまたがるアトミックデータ操作を調整するためです。作業単位をオーケストラ(リポジトリ)のディレクター(uow)と考えてください。

Entity Frameworkでは、作業単位パターンが本当に必要ですか?

必ずしも。 EFはすでに作業単位パターンを提供しています。依然として作業単位がある唯一の理由は、次の場合です。

  • 非EFデータソースをアトミックデータ操作に含めたい。
  • そのレイヤーのEF依存関係に依存せずに、ドメインで作業ユニットを使用したい。
  • eFが提供するよりも豊富な機能セットを備えた作業ユニットが必要です。ただし、これは、場合によっては、dbコンテキストをラップするのではなく拡張することで実行できる場合もあります。

質問への直接的な回答ではありませんが、接線的に関連しています。EntityFrameworkと組み合わせた作業ユニットとリポジトリの利点について 長い回答 を書きました。同じ主題を扱っているので、あなたにとって興味深い読みになるかもしれません。

3
Flater

nit-Of-Workパターン は、複雑なユースケースいくつかのオブジェクトが含まれ、多くの場合、異なるマスター/詳細テーブルにマップするオブジェクト。ユースケースの一部として、

  1. 必要なすべてのオブジェクトをデータベースから引き出します

  2. 結果に満足するまで、ユーザーがこれらのオブジェクト(ローカルコピー)を編集できるようにします。ここで「編集」とは、新しい「詳細オブジェクト」を追加または削除したり、特定の手順を元に戻したり、やり直したりすることを意味します。

  3. 最後に、1つのトランザクションでデータベースにオブジェクトの結果セットを書き戻します(または、ユーザーに変更を書き戻さない機会を与えます。その場合、 DBでは何も変更されません)。

たとえば、このような使用例は、オンラインショップの注文の作成(いくつかのアイテムが含まれる、注文アドレス、請求アドレス、支払い方法など)です。または、建物の建設をサポートするソフトウェアの複雑な構造コンポーネントを編集することもできます。または、保険契約を編集することもできます。この場合、契約は単一レコードのドキュメントではなく、多数のメタデータを持つ複数のオブジェクトに分割されます。

これらすべてのケースで、関連するデータをまとめて保持し、関係するオブジェクトへの変更を追跡する調整オブジェクトを用意することは、トランザクション全体で最適化された方法でデータベースに「全体」で書き戻すことができるため意味があります。それが作業ユニットオブジェクトの目的です。手順1と3は通常、リポジトリを使用します。

もちろん、EFのようなORMが自動変更追跡をサポートしている場合、その組み込みメカニズムに完全に依存できるユースケースでは、UoWは必要ない場合があります。しかし、「興味深い」現実の要件は必ずしもそれほど単純ではありません。EFの自動化は十分ではないか、十分に機能しない可能性があります。または、他のシステム、テクノロジー、またはレイヤーが含まれます。

したがって、UoWは、リポジトリと特定のサービスまたはユースケースの実装との間の追加のレイヤーにすぎず、特定のユースケースのニーズに合わせて設計されています。単一のDBテーブルでの簡単なCRUD操作のようなユースケースや、質問で示した単純な例のように、ほんの少しだけ複雑なユースケースの場合は、必ずしも必要ではありません。

3
Doc Brown