web-dev-qa-db-ja.com

EFの作業単位パターンとは何ですか?

私はEFを学んでおり、多くの例を見てきましたが、学習中にリポジトリと作業単位のパターンの使用について知るようになりました。リポジトリを使用する理由はわかりましたが、実際の作業単位については理解していません。

理解していないと、DALの理解が難しくなります。親切に私を案内してください。

ありがとう

37
haansi

DataContextまたはObjectContextは作業ユニットです。

したがって、DALはオブジェクトを保存、削除、取得し、DataContext/ObjectContextはオブジェクトを追跡し、トランザクションを管理し、変更を適用します。

これは例ですソリューションのアイデアを説明するためだけに

using(var context = new ObjectContext()) { // Unit of Work
    var repo = new ProductRepository(context);
    var product = repo.GetXXXXXXX(...);
    ...

    // Do whatever tracking you want to do with the object context. For instance:
    // if( error == false) { 
    //     context.DetectChanges();
    //     context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
    // }
}

そして、リポジトリは次のようになります。

public abstract class Repository {

    public Respository(ObjectContext context){
        CurrentContext = context;
    }

    protected ObjectContext CurrentContext { get; private set; } 
}

public class ProductRespository : Repository {
    public ProductRespository(ObjectContext context) : base(context){
    }

    public Product GetXXXXXX(...){
        return CurrentContext... ; //Do something with the context
    }
}    

別の方法は、作業単位(オブジェクトコンテキスト)をグローバルに配置することです。

作業単位の範囲を定義する必要があります。この例では、Webリクエストになります。実際の実装では、そのために依存性注入を使用します。

public static class ContextProvider {

    public static ObjectContext CurrentContext {
        get { return HttpContext.Items["CurrentObjectContext"];
    }

    public static void OpenNew(){
        var context = new ObjectContext();
        HttpContext.Items["CurrentObjectContext"] = context; 
    }

    public static void CloseCurrent(){
        var context = CurrentContext;
        HttpContext.Items["CurrentObjectContext"] = null;
        // Do whatever tracking you want to do with the object context. For instance:
        // if( error == false) { 
        //     context.DetectChanges();
        //     context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
        // }
        context.Dispose();
    }
}

この例では、ObjectContextが作業単位であり、現在のリクエストに含まれます。グローバルasaxに追加できるもの:

protected void Application_BeginRequest(object sender, EventArgs e){
    ContextProvider.OpenNew();
}

protected void Application_EndRequest(object sender, EventArgs e){
    ContextProvider.CloseCurrent();
}

リポジトリでは、ContextProvider.CurrentContext

34
Ivo

エンタープライズソフトウェア開発で最も一般的な設計パターンの1つは、作業単位です。 Martin Fowlerによれば、 nit of Workパターン 「ビジネストランザクションの影響を受けるオブジェクトのリストを維持し、変更の書き込みと同時実行の問題の解決を調整します。」

作業単位パターンは、必ずしも明示的に自分で作成するものではありませんが、パターンは私が知っているほぼすべての永続化ツールに表示されますの。 NHibernateのITransactionインターフェイス、LINQ to SQLのDataContextクラス、およびEntity FrameworkのObjectContextクラスは、すべて作業ユニットの例です。さらに言えば、由緒あるDataSetを作業単位として使用できます。

詳細情報について こちら をクリックしてこの記事を読んでください。良い記事です。

ASP.NET MVC(MVC 4およびEF 5)アプリケーション(9/10)でのリポジトリおよび作業単位パターンの実装に関するチュートリアルについては、 here をクリックしてください。

EF 6およびMVC 5のチュートリアルについては、 こちら をクリックしてください

これが助けてくれることを願っています、助けてくれました!

enter image description here

26
Deep

作業単位

ビジネストランザクションの影響を受けるオブジェクトのリストを維持し、記述を調整します
変更なし、同時実行性の問題の解決。

enter image description here

データベースにデータを出し入れする場合、変更内容を追跡することが重要です。そうしないと、そのデータはデータベースに書き戻されません。同様に、作成した新しいオブジェクトを挿入し、削除したオブジェクトを削除する必要があります。

オブジェクトモデルを変更するたびにデータベースを変更できますが、これにより、非常に小さなデータベース呼び出しが多数発生する可能性があり、非常に遅くなります。さらに、インタラクション全体でトランザクションを開いておく必要があります。これは、複数の要求にまたがるビジネストランザクションがある場合は非現実的です。一貫性のない読み込みを避けるために、読み込んだオブジェクトを追跡する必要がある場合、状況はさらに悪化します。

作業ユニットは、データベースに影響を与える可能性のあるビジネストランザクション中に行うすべてを追跡します。完了すると、作業の結果としてデータベースを変更するために実行する必要があるすべてのことがわかります。

http://martinfowler.com/eaaCatalog/unitOfWork.html

14
Matt Ball