39

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

理解していないと、DAL の理解が難しくなります。よろしくお願いします。

ありがとう

4

3 に答える 3

37

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
    }
}    

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

作業単位の範囲を定義する必要があります。この例では、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

于 2012-05-27T18:09:06.243 に答える
15

作業単位

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

ここに画像の説明を入力

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

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

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

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

于 2012-05-27T18:09:13.287 に答える