Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the unit of work pattern in EF?

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.

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

Thanks

like image 516
haansi Avatar asked May 27 '12 18:05

haansi


People also ask

What is unit of work pattern in Entity Framework?

Unit of Work is the concept related to the effective implementation of the repository pattern. non-generic repository pattern, generic repository pattern. Unit of Work is referred to as a single transaction that involves multiple operations of insert/update/delete and so on.

What is unit of work pattern in MVC?

The Unit of Work pattern is used to group one or more operations (usually database CRUD operations) into a single transaction or “unit of work” so that all operations either pass or fail as one unit.

Do we need unit of work with Entity Framework?

No need for repositories and unit of work with Entity Framework Core.

What is unit of work in .NET core?

The Unit of Work is a type of business transaction, and it will aggregate all Repository transactions (CRUD) into a single transaction. Only one commit will be made for all modifications. If any transaction fails to assure data integrity, it will be rolled back.


1 Answers

The DataContext or ObjectContext is the Unit of Work.

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

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.

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:

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

like image 150
Ivo Avatar answered Oct 05 '22 16:10

Ivo