Organizationally, where should I put common queries when using Entity Framework Code First?

Looks like the repository pattern is solution for everything … Repository is not a silver bullet!

I’m using the repository pattern with EF everyday because when I started my current project several months ago it looked like recommended solution. My conclusions:

  • Repository makes interaction with EF much harder. Just browse questions related to EF tags and you will see what complexities must be handled directly on the context, changetracker, etc.
  • Generic repository is something that works for CRUD operations but not for real DDD scenarios. Once your repository works with aggregate roots (DDD) generic approach fails.
  • Unit testing doesn’t work at all because general idea that you will mock repository and test your upper layer without dependencies to EF and database fails once you expose IQueryable. Linq-to-entities is only subset of Linq-to-objects and mock doesn’t handle referential integrity so many times I saw green unit tests and runtime exceptions. The correct testing approach with EF are integration tests. Mocking repository is only for testing real business logic not related to data access. If you don’t have integration test for your business method accessing or persisting data you didn’t test it.
  • Exposing specialized methods like GetByXXX is just step back. Most of these methods are used only once. You will end with the code similar to repositories used for wrapping stored procedures calls. Many developers like ORM just because they can avoid such rigid architecture.

EF itself already offers repository pattern – DbSet and ObjectSet are repositories and DbContext and ObjectContext are Unit of works. So in my opinion repository pattern is overused. It can be useful in large projects where you need strict layering or in case of placing additional logic to its methods. Using repository just because you want to wrap access to EF is often valueless code and just additional layer of complexity.

You can in the same way create reusable methods defining your queries.

Leave a Comment