Do we need the repository pattern?
As we learn new technologies, we discover new mistakes. The Entity Framework makes data access very quick to develop, but also introduces a new set of mistakes that can be made. On my last project I used the Entity Framework Profiler and found my code blighted with a scourge of N+1 problems. I discussed this in my blog post Reviewing my data access layer using the Entity Framework Profiler.
I was also worried that my code wasn’t testable. From what I’d read, the repository pattern seemed to be the agreed best practice for making your data access testable.
However my N+1 problems led me to read a lot of blog posts by Entity Framework Profiler creator Ayende Rahien. In his post Repository is the new singleton he explains why the repository pattern is no longer required when you have a decent ORM such as NHibernate or Entity Framework. It just adds a layer of abstraction over the ORM, which is in itself a data access abstraction.
This layer of abstraction can distance you from the features of your ORM. One of these features is allowing you to specify exactly which tables you want to be retrieved in your query. This is one of the things that helps prevent N+1 problems. In the Entity Framework you do this using the include method. I’ve seen some Entity Frameworks Repository examples that use the Include method, but most don’t.
I still see the repository pattern put forward as best practice and although I agree with Ayende, the repository still seems to be the majority point of view. This excellent article by Tugberk Ugurlu explains how to create a testable generic repository with EF. I have previously found that using the repository pattern leads to repeating myself a lot, and this implementation fixes that. When I wrote this article his generic repository didn't give you access to the Include method which would have led to N+1 problems. He has informed me in the comments this has now been fixed, and in a nice elegant way. Even with this very nice implementation, does the repository pattern gives us any extra benefit if there is another way to create a testable data access layer?
Ayende’s suggested alternative to using the repository pattern and keeping things testable is to use a mockable interface to your ORM’s data context. In NHibernate it sounds like this is quite straight forward, however it wasn’t immediately obvious how you could do this using Entity Framework. The advice I found online using this approach was quite scattered, so I’ve brought what I found together in this post:
This approach has worked really nicely in my project and I think it is better than using the repository pattern. I’m still really open to being told I’m wrong and that repositories rock, but I no longer see what they bring to the party.
Tugberk said
Hi,
Came across your post. Thanks for the link to my post. @bmccord sent me a PR couple of weeks ago and GenericRepository.EF package now has AllIncluding method with a nice lambda syntax. Now, you can do something similar to following:
var fooBar = _myRepo.AllIncluding(x => x.Foo, x => x.Bar);
For me, repository pattern is always useful. I don't know how I feel about that tomorrow but for now I am happy with that.
Richard Garside said
@tugberk with that feature your generic repository is very compelling indeed. I'll update this post, so it's clear it now includes a way to use include.
The lambda syntax looks really neat as well.
Arjun said
said 17 August 2012 02:52:15 Hello !!
Thanks for the simplicity and the quality of you article. I really appreciate the reusable benefit on the DRY.
While trying to do it myself, i got the idea to make all my Entity framework classes inherit from a Common class called Identifiable. This class only focus on the capability of classes to have an Id(mapped to the corresponding unique Id in database).
Since i can identify every object with its Id, i can implement a concrete method GetById() like this :
public T GetById(int id) { return this.Context.Set<T>().Single(p => p.ID == id);
}
And finally i just have one an generic Class GenericRepository to manage my domain model.
KMacGregor said
I stumbled across your blog and read through. Good discussion.
With the advent of LINQ, I still used the repository pattern, but much like the generic repository, I incorporated it into my designs to make things better (reduce method overload hell)
With the advent of code first in entity framework, I have stopped using the repository pattern. I wrap my context with an interface and code against that. With MOQ i am easily able to unit test.
There is nothing that the repository pattern provides that cannot be accomplished with the interface wrapper. All it would do is add an abstraction layer on top of an abstraction later.
Hans said
Ayende explained idiot proof why the repository pattern is just cruft in his latest presentation:
http://www.youtube.com/watch?v=0tlMTJDKiug
And he is right, there's nothing to discuss.