【问题标题】:What is the unit of work pattern in EF?EF中的工作单元模式是什么?
【发布时间】:2012-05-27 18:06:07
【问题描述】:

我正在学习 EF 并且看过很多示例,在学习过程中我开始了解使用存储库和工作单元模式。我知道为什么要使用存储库,但我不了解工作单元的真正含义。

不理解会使 DAL 难以理解。请指导我。

谢谢

【问题讨论】:

标签: c# .net entity-framework design-patterns


【解决方案1】:

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

【讨论】:

  • ivowiblo 你能给出一些代码示例吗?或链接?谢谢
  • 我实现工作单元的方式完全相同,只是我懒加载上下文而不是 OpenNew。但是,当我使用Application_EndRequest 处理上下文时,我仍然感到不安。你知道事件触发和完成的保证程度吗?
  • 请求结束时总会调用它。 NHibernate 使用它实现它的会话管理,并且总是作为一种魅力。该模式称为 open-session-in-view
【解决方案2】:

企业软件开发中最常见的设计模式之一是工作单元。根据 Martin Fowler 的说法,Unit of Work pattern“维护受业务事务影响的对象列表,并协调写入更改和解决并发问题。”

工作单元模式不一定是您自己明确构建的,但该模式出现在我所知道的几乎所有持久性工具中。 NHibernate 中的 ITransaction 接口、LINQ to SQL 中的 DataContext 类和实体框架中的 ObjectContext 类都是工作单元的示例。就此而言,古老的 DataSet 可以用作工作单元

更多详细信息请点击here阅读这篇文章,很好。

有关在 ASP.NET MVC(MVC 4 和 EF 5)应用程序中实现存储库和工作单元模式的教程(10 个中的 9 个),请单击 here

EF 6 和 MVC 5 教程请点击here

我希望这会有所帮助,它帮助了我!

【讨论】:

    【解决方案3】:

    工作单元

    维护受业务事务影响的对象列表,并协调更改的写入和并发问题的解决。

    当您将数据导入和导出数据库时,重要的是 跟踪您所做的更改;否则,该数据将不会 写回数据库。同样,您必须插入新的 您创建的对象和删除您删除的任何对象。

    您可以在每次更改对象模型时更改数据库,但是 这可能会导致大量非常小的数据库调用,最终导致 很慢。此外,它要求您进行交易 对整个交互开放,如果你有一个 跨越多个请求的业务事务。情况是 更糟糕的是,如果你需要跟踪你读过的对象,所以你 可以避免不一致的读取。

    工作单元跟踪您在业务期间所做的一切 可能影响数据库的事务。完成后,它会计算 结果是改变数据库需要做的所有事情 你的工作。

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

    【讨论】:

    • 这不是一个真正的答案。您刚刚从资源中复制并粘贴了描述。
    • @MartinBean:部分问题是I do not have understanding of unit of work really is.。由于 M.Fowler 写得很好,因此引用的摘录是主题。一个链接是不够的,因为仅链接的答案由于它们被破坏的能力而非常讨厌。因此,提供链接并复制描述似乎是一个极简的有效部分答案。简约,部分,但仍然是一个答案。这当然是我个人的看法。
    • 好答案,先生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 2016-01-15
    • 2016-05-21
    相关资源
    最近更新 更多