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.