C# EF 中的工作单元模式是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10776121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:12:40  来源:igfitidea点击:

What is the unit of work pattern in EF?

c#.netentity-frameworkdesign-patterns

提问by haansi

I am learning EF and have seen many examples, and during my learning I came to know about using repository and unit of work patterns. I got why to use repository but I do not have understanding of unit of work really is.

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

Having no understanding is making DAL understanding difficult. Kindly guide me.

不理解使 DAL 理解变得困难。请指导我。

Thanks

谢谢

采纳答案by Ivo

The DataContext or ObjectContext is the Unit of Work.

DataContext 或 ObjectContext 是工作单元。

So, your DAL will save, delete and retrieve objects and your DataContext/ObjectContext will keep track of your objects, manage transactions and apply changes.

因此,您的 DAL 将保存、删除和检索对象,而您的 DataContext/ObjectContext 将跟踪您的对象、管理事务并应用更改。

This is an example just to illustrate the idea of the solution.

这是一个示例,只是为了说明解决方案的想法

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);
    // }
}

And your repository will look like:

您的存储库将如下所示:

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

Another way is to put the unit of work (Object context) globally:

另一种方法是将工作单元(对象上下文)全局放置:

You need to define what will be your unit of work scope. For this example, it will be a web request. In a real world implementation, I'd use dependency injection for that.

您需要定义您的工作范围单元。对于此示例,它将是一个 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();
    }
}

In this example, ObjectContext is the unit of work and it will live in the current request. In your global asax you could add:

在这个例子中,ObjectContext 是工作单元,它将存在于当前请求中。在您的全局 asax 中,您可以添加:

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

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

In your Repositories, you just call ContextProvider.CurrentContext

在您的存储库中,您只需调用 ContextProvider.CurrentContext

回答by Matt Ball

Unit of Work

Maintains a list of objects affected by a business transaction and coordinates the writing
out of changes and the resolution of concurrency problems.

enter image description here

When you're pulling data in and out of a database, it's important to keep track of what you've changed; otherwise, that data won't be written back into the database. Similarly you have to insert new objects you create and remove any objects you delete.

You can change the database with each change to your object model, but this can lead to lots of very small database calls, which ends up being very slow. Furthermore it requires you to have a transaction open for the whole interaction, which is impractical if you have a business transaction that spans multiple requests. The situation is even worse if you need to keep track of the objects you've read so you can avoid inconsistent reads.

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

工作单位

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

在此处输入图片说明

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

您可以在每次更改对象模型时更改数据库,但这可能会导致大量非常小的数据库调用,最终会变得非常缓慢。此外,它要求您为整个交互打开一个事务,如果您有一个跨越多个请求的业务事务,这是不切实际的。如果您需要跟踪已读取的对象以避免不一致的读取,情况会更糟。

工作单元会跟踪您在可能影响数据库的业务事务期间所做的一切。完成后,它会计算出由于您的工作而需要完成的所有更改数据库。

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

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

回答by Deep

One of the most common design patterns in enterprise software development is the Unit of Work. According to Martin Fowler, the Unit of Work pattern"maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems."

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

The Unit of Work pattern isn't necessarily something that you will explicitly build yourself, but the pattern shows up in almost every persistence tool that I'm aware of. The ITransaction interface in NHibernate, the DataContext class in LINQ to SQL, and the ObjectContext class in the Entity Framework are all examples of a Unit of Work. For that matter, the venerable DataSet can be used as a Unit of Work.

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

For more detail info Please click hereto read this article, it's a good one.

有关更多详细信息,请单击此处阅读这篇文章,这是一篇很好的文章。

For Tutorial on Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC (MVC 4 and EF 5) Application (9 of 10) please click here

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

For EF 6 and MVC 5 tutorial please click here

有关 EF 6 和 MVC 5 教程,请单击此处

I hope this will help, it helped me!

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

enter image description here

在此处输入图片说明