Unit of Work is the concept related to the effective implementation of the Repository Pattern. To understand this concept in better it is important to understand the concept of the Repository Pattern. We will not get into the details of the Repository Pattern in this discussion. But a small idea of this concept is necessary to proceed further.
The Repository Pattern
A repository is nothing but a class defined for an entity, with all the operations possible on that specific entity. For example, a repository for an entity Customer, will have basic CRUD operations and any other possible operations related to it. A Repository Pattern can be implemented in Following ways:
- One repository per entity (non-generic) : This type of implementation involves the use of one repository class for each entity. For example, if you have two entities Order and Customer, each entity will have its own repository.
- Generic repository: A generic repository is the one that can be used for all the entities, in other words it can be either used for Order or Customer or any other entity.
Unit of Work in the Repository Pattern
Unit of Work is referred to as a single transaction that involves multiple operations of insert/update/delete and so on kinds. To say it in simple words, it means that for a specific user action (say registration on a website), all the transactions like insert/update/delete and so on are done in one single transaction, rather then doing multiple database transactions. This means, one unit of work here involves insert/update/delete operations, all in one single transaction.
To understand this concept, consider the following implementation of the Repository Pattern using a non-generic repository, for a Customer entity.
The code above seems to be fine. The issue arises when we add a repository for another entity, say Order. In that case, both repositories will generate and maintain their own instance of the DbContext. This may lead to issues in the future, since each DbContext will have its own in-memory list of changes of the records, of the entities, that are being added/updated/modified, in a single transaction/operation. In such a case, if the SaveChanges of one of the repository fails and other one succeeds, it will result in database in-consistency. This is where the concept of UnitOfWork is relevant.
To avoid this, we will add another layer or intermediate between the controller and the Customer repository. This layer will act as a centralized store for all the repositories to receive the instance of the DbContext. This will ensure that, for a unit of transaction, that spans across multiple repositories, should either complete for all entities or should fail entirely, as all of them will share the same instance of the DbContext. In our above example, while adding data for the Order and Customer entities, in a single transaction, both will use the same DbContext instance. This situation, without and with Unit of work, can be represented as in the following :
In the above representation, during a single operation, that involves Customer and Order entities, both of them use the same DbContext instance. This will ensure that even if one of them breaks, the other one is also not saved, thus maintaining the database consistency. So when SaveChanges is executed, it will be done for both of the repositories.
Let us implement this concept in our example. We add a new class called UnitOfWork and this class will receive the instance of the DbContext. The same class will further generate the required repository instances, in other words repository instances for Order and Customer and pass the same DbContext to both the repositories. So our UnitOfWork will be like the following:
And, our Customer Repository will be changed, to receive the instance of DbContext from the unit of work class. See the code below:
Similarly, we can have the code for the Order repository. Finally, our controller code will be like the following :
Here, both the Order and Customer repository use the same instance of DbContext and we are executing the save changes using the instance unit of work class. So the changes of a single transaction are either done for both or none. Run the code and see the results.
So this was about the concept of unit of work in the Repository Pattern. Any suggestions are welcome.

Tom FanaraPosted Sep 13, 2022, 2:26 AM
Hello sir is there source code for this? Its very clear but want to see the entire solution.
ID LogPosted Jul 21, 2021, 7:19 PM
Hi thanks, but where is Entities class?
stelios chPosted Nov 2, 2020, 11:56 AM
But what about when you have business layer? in 3layer architecture the flow goes PL>BLL>DAL(REPO) Since Presentation layer cannot have access to DAL then how we can use bll with Unit of work? for exampe in controller we must save a CustomerService.Update(customer); SupplierService.Update(supplier); ItemService.Update(Item); and maybe other things too.. should we implement a unit of work and pass it in BLL constructor and therefor BLL pass UnitOfWork to e.g CustomerRepository Constructor
Lalit RaghavPosted Sep 15, 2019, 4:12 AM
Very very Nice Article Sir jee
Omkar kPosted Sep 1, 2019, 10:40 AM
Simple and very understandable. Thank you Jasminder.
Moni MoniPosted Jul 12, 2019, 1:13 AM
Hi Jasminder. This post is grate but I no idea how to make unit test for this UnitOfWork and Repository pattern. Can you help me? Thanks :)
Siphenathi PantshwaPosted May 29, 2019, 9:13 AM
Do customer and Order entity have the relationship?
Dheeraj KumarPosted Nov 18, 2018, 12:03 PM
Good article but I have one doubt , here Unit Of Work is just sharing context , but real idea of Unit of Work of having single Unit of operation/transaction , which I can't see here, may be I did not understand it and I need to read it multiple times :-) , and we are creating instance of Unit of work in this class ,this way we are depending on implementation rather on abstraction though we have allowed DI via constructor of concrete but should we do it like this … please help me understand this , sorry if I am not able to understand this great post :-)
Cipher CoderPosted Oct 17, 2018, 4:27 AM
Jasminder, cool dear, seems now I have understood the concept. Suggest you keep writing, as you've got a beautifully lucid style of writing!! Ciao
Nikhil SanganiPosted Sep 25, 2018, 2:02 AM
Very well explained thank you
Dennis ThomasPosted Feb 15, 2018, 2:38 AM
Very well explained Jasminder. Thank you!
madan prabhakaraPosted Jan 29, 2018, 5:38 AM
I have a query. We have data maintained in 2 databases - Oracle (Product) and SQL(Customer). Now we need to save changes in both these databases. So how can I adopt the repository pattern and Unit of work pattern to accomplish the same?
saravana bharathiPosted Nov 17, 2017, 9:53 AM
Nice article to understand Unit of Work in repository pattern.
Rajesh JhaPosted Oct 10, 2017, 3:29 AM
Great article. Point to point clearly described.
akash pawarPosted Jun 21, 2017, 8:04 AM
Sir , Do you have any practical demo dependancy injection with autofac if yes then please upload
Himanshu VinchhiPosted Mar 27, 2017, 9:13 AM
Very well explained.
Bimal DasPosted Feb 22, 2017, 11:18 PM
You are great sir :)
Ahmed AbdiPosted Aug 5, 2016, 1:10 PM
Great Article , Thanks Jasminder
Akhilesh PanditPosted Jun 10, 2016, 10:31 AM
Hi Jasminder can u please upload this project?
Rasik Bihari TiwariPosted Jan 30, 2016, 7:36 PM
Hi Jasminder! Really nicely written article. I noticed one thing which seems like an error here. Please correct me if I'm wrong but your revised implementation of CustomerRepository class (to enable unit of work pattern) should not have SaveChanges method as the saving of changes is now being managed centrally by UnitOfWork class (holding all the repositories) through the object of Entities class. Same gets reflected when UnitOfWork class gets used in ContactsController class. I request you to please update the code snippet snapshot if possible to avoid any confusion for the readers.
Former memberPosted Jan 8, 2016, 5:40 AM
would allow us to download your project in zip format so we can extract and run the project in our pc. thanks
Manzoory MPosted Oct 29, 2015, 7:17 AM
Nice Article. One question arises. Suppose we need to get the CustomerId after inserting a new customer, and save this CustomerId in our Orders Table. What Should we do in this situation?
Pablo Manuel ArayaPosted May 26, 2015, 11:39 PM
Thanks Jasminder for you post!. One short question : how can I do to Disponse() the DbContext ? I should have an Dispose() method on the UnitOfWork class. Kind regards
Anupam SinghPosted Aug 16, 2014, 1:47 AM
Hi Jasminder, I to prefer a generic Unit of Work class while working with repository pattern.