Introduction

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Repository provides an in-memory like collection interface for accessing domain objects. So as far as the consuming component is concerned, it uses the repository just like a collection when working with Domain objects. The repository then neatly abstracts the internal mechanics of how the Add / Remove calls to the repository translate to the actual data access calls to the data store. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

So with the repository we get a nice abstraction that provides us with persistence ignorance and a nice separation of concerns where the responsibility of persisting domain objects is encapsulated by the Repository leaving the domain objects to deal entirely with the domain model and domain logic.Here are some reasons for using repository pattern in data access layer in place direct access the database code-

Duplicated code

A higher potential for programming errors

Weak typing of the business data

Difficulty in centralizing data-related policies such as caching

An inability to easily test the business logic in isolation from external dependencies

Notice that, here I also implement IDispose interface to dispose the context manually.To get the name of Entityset, here I have used typeof, but you can do a metadata query to retrieve the EntitySet name:

Here I am not going a little into the code. I have used ObjectQuery to get the features of MargeOption and EnablePlanCaching properties:

ObjectQuery.EnablePlanCaching Property-indicates whether the query plan should be cached.Plan-caching caches information which is computed as part of putting together the query itself. By caching this, a subsequent execution of the same query (even if you change parameter values) will run much faster than the first one. This information is cached per app-domainso you will generally benefit from the query cache across multiple client requests to the same web app and the like. Here allDoQuery methods are responsible to queries and other query method likeSelectAll orSelect methods internally use theseDoQuery methods with various parameters.

Setting MergeOption to NoTracking has helped us to take advantage of the EF ability to return data that doesn’t need to be tracked by the context. Say I don’t have any plan to make changes to that data. Therefore, I like to avoid the performance hit taken when EF creates ObjectStateEntry instances for each object it’s tracking, as well as forcing the context to be aware of any changes made to those objects.

SelectByKey is creating a LINQ expression using Expression tree for Primary key and During creating the repository on an entity you can supply this Primary Key property as string. While using the POCO as you entity you can set attribute programming to serve this kind of job.

TrySameValueExist is doing the same job by allow you to set customize field and value comparison there. What will do is create the Expression for you and also add the PrimaryKey comparison so that it excludes the object that you are querying for (and where PrimaryKey != currentObjectPrimaryKey).

Add and Delete method simply respectively call the AddObject and DeleteObject Method of ObjectContext. AddOrAttach method is for special situation where you don’t know whether object is already added or not. It is expensive since it will do query to database to check the existence.

The specification pattern can implement a re-usable business logic component that can be passed around to satisfy certain business criteria. The specification object has a clear and limited responsibility, which can be separated and decoupled from the domain object that uses it. I would highly recommend reading the white paper by Martin Fowler and Eric Evans on the Specification pattern.

You can write your own specification by implementing your interface like RoleSpecification and put down your business logic there. For general use, you can also implement the Interface; such composite specification like this:

Here some operator overloading has been applied here is to combine the lambda expression (or predicate) of each specification (left and right side of a composite specification) to create a new lambda expression.This new lambda expression is going to use for querying. So It will help you while you are working with multiple specification already defined as your business rule.

To use this Repository class from your business layer, one thing I must say that I am sharing a single context in the CRUD process/operation. You must keep alive the context in your entire process of a crud operation. For this, I make a UnitOfWork on top of all.

Here Unit of Work has been introduced as umbrella over multiple repositories and shared by all repository in place of the object context directly and method like save, transaction can be switched over there. And here is that implementation.

Repository is kind of mediator to connect business layer with data access. So your business layer should be aware of this repository class. Now, In my BLLRoleManagement class, say I have a method to delete User. That will be something like this:

Here It will initialize a ObjectContext instance which will be used in you entire process/workflow of an operation. For this, I have provided a factory method inside Unit of Work which create a repository for you using that ObjectContext . Delete all related entities associated with User and then delete User. To share the same context in this delete process, I will call this method like this

new BLLRoleManagement().DeleteUser(userID);

Surely it has a lot of area to improve. I have used some interfaces here those can be used with dependency injection to decouple your code from EF. Hope its help. So here is my end of the discussion on repository pattern implementation with Entity framework. Good luck.

Thank you very much. First thing is that you can change it according to your need. If you use DBContext then I think there is a dedicated method "Find" for this which also try 1st level caching (try in-memory object if exist otherwise it go for DB findings) from EF 4.1. In my sample I have used GUID as PK that why it is string but you can change if you need. this article has been developed at 2009 when ObjectContext doesn't offer my any method like that. I don't need to change this article in this days since I am trying to explain repository and specification pattern to fit with EF (which not necessary to be used, only if you need it). But its only a concept and you need to change it according to you application.

- Illusion of hiding details/abstracting the ORM. You can not change the in use ORM easily because you are using the repository classes. Different ORMs have different LINQ implementations and capabilities. NHibernate has 2nd level caching capability and EF, not. EF has different 1st level caching implementation than NHibernate. NHibernate does not support a lot LINQ features of EF and so on.
- Working with single entities and do not using the unit of work pattern. In real world you need to work with multiple entities in one transaction and SaveChanges method should be called at the end of the unit of work and not in the repository classes.
- Also do not using the UOW causes multiple round trips to the database instead of using just one connection per transaction.
- When you are disposing the ctx in the repository class, it will be impossible to use dependency injection across multiple classes in web applications.

can you provide me with a link to a article that implements the UoW pattern the right way? i'm searching right now, but i'm alread having problems with repositories and a good push on the right direction would help a lot.

I'm brazilian and english (well, human languages in general) aren't my best skill, so, sorry by my english. (if you want we can speak in C# or VB.Net =p)

I have updated this article with sample code. Some portion of code has been updated For example: Get EntitySet-Name is currently retrieving from meta data and AND/OR support has been added to specification class(In .net 3.5 there was a limitation to work operator overloading of Expression, which has been resolved in later version). Also I have added some code explanation which I did avoid in my previous revision.
Hope that will help. Good luck.

It has been published about three years ago and it has been writing on ef v1.1.

Given the amount that's changed since the original post: -- The Opinions and Conventions of MVC have matured -- EF Code First makes EF far more accessible (and therefore: mainstream) -- 3rd party utilities have matured -- Experience levels of senior-level devs has matured

The rigor and thoroughness you've applied to the explanation would be all that much more valuable if you undertook a more comprehensive re-write.

this is a typical case of over-architecting.
A pattern is useful not just because you can use it to prove you can do "correct design" or using the "good practices", it is useful because it can give you something: flexibility, speed, test-ability, scalability, etc.

you need to consider that EF already have Repository and UoW implemented. so, if you are about to wrap that in a second layer. That should be "easier" to use than just using EF directly.

Thanks for your judgement!! its not on "good practices" mood,it help me to have a single entry point of all
db related code, implementing Logging and Caching , audit trial ....its totally up to you whether you want it or not ....its just an concept that I share and Im sure it helps some people get some ready to use code. ....yes, Surely , I also feel there is always some areas of improvement...and this article has that also....I am not worry about anybody's vote , all I am worry about reader's feedback that I may missed here. It has been published about three years ago and it has been writing on ef v1.1.

So EF implements UoW and Repository patterns, or so I've heard. Yet I've never seen a good example of how to use EF properly WITHOUT it being directly in the presentation layer. In my case a MVC project. Please if you know of a simpler implementation, share it.

They do implement those patterns, a DbContex or ObjectContext would be your UoW, and the ObjectSet or Set inside are your repositories, then, there is no need to rebuild the pattern around the pattern.

so, if you have a UoW you use it in your site from the presentation layer right? why not EF then? now, if the problem is that you dont want dependencies/references to EF (which makes sense) I would recommend to use Unity Framework and inject those into your project. All you need to do is wrap that around with an interface that return IQueryable.

IQueryable is the center of all here, is what makes those pattern-wrapping obsolete, when Martin Fowler wrote that in the book, he referred to "collections", and IQueryable is more powerful than that.

Actually our presentation layer would call services, which would then call the DB or UoW, but same difference. Abstracting out EF is not my intention, I'd rather have testable code. IE I don't want to have to use a database to test code. I've always assumed this was the reason people implemented their own UoW and Repository patterns. I suppose I'll go look and see how testable EF is on it's own.

And I certainly plan on using a dependency injection framework. Unfortunately I learn from example and most examples out there are so trivial they are useless when it comes to wiring all this up in a real app that doesn't get things one entity at a time.