Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

During a job interview, I was asked to explain why the repository pattern isn't a good pattern to work with ORMs like Entity Framework. Why is this the case?

share|improve this question

migrated from stackoverflow.com Dec 28 '12 at 14:53

This question came from our site for professional and enthusiast programmers.

20  
it was a trick question –  Omu Dec 12 '12 at 21:34
2  
I would probably have answered to the interviewer that Microsoft use the repository pattern very often while they demonstrate the entity framework :| . –  Laurent Bourgault-Roy Dec 28 '12 at 17:12
    
So what was the interviewer's reason for it not being a good idea? –  Bob Horn Dec 30 '12 at 15:42
2  
The funny fact is that searching for "repository pattern" in Google gives the results which are mostly related to Entity Framework and how to use the pattern with EF. –  MainMa Dec 31 '12 at 18:43
2  
check ayende's blog ayende.com/blog. Base on what I know, he used to use Repository Pattern but eventually gave it up in favor of the Query Object Pattern –  Daskul Feb 2 at 8:30

6 Answers 6

up vote 30 down vote accepted

I don't see any reason for Repository pattern to NOT work with Entity Framework. Repository pattern is an abstraction layer you put on your data access layer. Your data access layer can be anything from pure ADO.NET stored procedures to Entity Framework or an XML file.

In large systems, where you have data coming from different sources (database/ XML /Web service), It is good to have an abstraction layer. Repository pattern works well in this scenario. I do not believe Entity framework is enough abstractive to hide what is going behind the scene.

I have used Repository pattern with Entity Framework as my data access layer method and am yet to face a problem.

Another advantage of abstracting the db context with a Repository is unit testability, You can have your iRepositary interface to which has 2 implentation, one (the real Repositary) which uses dbContext to talk to the database and the second, FakeRepositary which can return in memory objects/mocked data. This makes your IRepositary unit testable, thus other parts of code which uses IRepositary

share|improve this answer
    
I didn't said it will not work , I am also worked with repository pattern with EF , but today I was asked why IT IS NOT GOOD to use the pattern with DataBase , application that using Database –  StringBuilder Dec 12 '12 at 21:08
1  
Ok , since this is the most popular answer I'll chose it as Correct Answer –  StringBuilder Dec 15 '12 at 12:21
6  
When was the last time that most popular == correct? –  HDave Aug 30 '13 at 19:16
3  
DbContext is already a repository, the repository is meant to be a low level abstraction. If you want to abstract different data sources create objects to represent those. –  Daniel Little Dec 3 '13 at 4:34
    
There are many reasons not to use Repository pattern with OR Mappers. It's two years after this answer was given. Now you can find all of them easily on Google. –  Peri Mar 5 at 23:09

The single best reason to not use the repository pattern with Entity Framework? Entity Framework already implements a repository pattern. DbContext is your UoW (Unit of Work) and each DbSet is the repository. Implementing another layer on top of this is not only redundant, but makes maintenance harder.

People follow patterns without realizing the purpose of the pattern. In the case of the repository pattern, the purpose is to abstract away the low-level database querying logic. In the old days of actually writing SQL statements in your code, the repository pattern was a way to move that SQL out of individual methods scattered throughout your code base and localize it in one place. Having an ORM like Entity Framework, NHibernate, etc. is a replacement for this code abstraction, and as such, negates the need for the pattern.

However, it's not a bad idea to create an abstraction on top of your ORM, just not anything as complex as UoW/repostitory. I'd go with a service pattern, where you construct an API that your application can use without knowing or caring whether the data is coming from Entity Framework, NHibernate, or a Web API. This is much simpler, as you merely add methods to your service class to return the data your application needs. If you were writing a To-do app, for example, you might have a service call to return items that are due this week and have not been completed yet. All your app knows is that if it wants this information, it calls that method. Inside that method and in your service in general, you interact with Entity Framework or whatever else you're using. Then, if you later decide to switch ORMs or pull the info from a Web API, you only have to change the service and the rest of your code goes along happily, none the wiser.

It may sound like that's a potential argument for using the repository pattern, but the key difference here is that a service is a thinner layer and is geared towards returning fully-baked data, rather than something that you continue to query into, like with a repository.

share|improve this answer
7  
This appears to be the only correct answer. –  Mike Chamberlain Jan 16 at 23:29
    
This is something I have been wondering as well, as it was my thought too that the DbContext is the Unit of Work, so there's no need to create a layer above it that essentially just delegates back to an internal instance of DbContext. About the only reason I can see for having an abstraction layer is that you can't mock DbContext, so you have to rely on an actual database with data to do unit/integration testing. –  Wayne M Jan 24 at 15:01
2  
You can mock DbContext in EF6+ (see: msdn.microsoft.com/en-us/data/dn314429.aspx). Even in lesser versions, you can use a fake DbContext-like class with mocked DbSets, since DbSet implements an iterface, IDbSet. –  Chris Pratt Mar 6 at 0:23
    
this description sounds more like my idea of a repository layer. a wrapper that has methods that return and act on data entities. I guess my repos are pretty thin to begin with –  TheZenker Mar 26 at 12:10
1  
@TheZenker, you may not have been exactly following the repository pattern. The strictest difference is the return value. Repositories return queryables, whereas services should return enumerables. Even that's not really that black and white, as there's some overlap there. It's more in how you use it. A repository should just return the set of all objects, which you then further query into, while the service should return the final dataset, and should not support further querying. –  Chris Pratt Mar 27 at 14:31

Here's one take from Ayende Rahien: Architecting in the pit of doom: The evils of the repository abstraction layer

I'm not sure yet whether I agree with his conclusion. It's a catch-22 - on the one hand, if I wrap my EF Context in type-specific repositories with query-specific data retrieval methods, I am actually able to unit test my code (sort of), which is almost impossible with Entity Framework alone. On the other hand, I lose the ability to do rich querying and semantic maintenance of relationships (but even when I have full access to those features I always feel like I'm walking on egg shells around EF or any other other ORM I might choose, since I never know what methods its IQueryable implementation might or might not support, whether it will interpret my adding to a navigation property collection as a creation or merely an association, whether it is going to lazy or eager load or not load at all by default, etc., so maybe this is for the better. Zero-impedance object-relational "mapping" is something of mythological creature - maybe that is why the latest release of Entity Framework was codenamed "Magic Unicorn").

However, retrieving your entities through query-specific data retrieval methods means that your unit tests are now essentially white-box tests and you have no choice in this matter, since you must know in advance exactly which repository method the unit under test is going to call in order to mock it. And you're still not actually testing the queries themselves, unless you also write integration tests.

These are complex problems that need a complex solution. You can't fix it by just pretending that all your entities are separate types with no relationships between them and atomize them each into their own repository. Well you can, but it sucks.

Update: I have had some success using the Effort provider for Entity Framework. Effort is an in-memory provider (open source) that allows you to use EF in tests exactly the way you would use it against a real database. I am consider switching all the tests in this project I'm working to use this provider, since it seems to make things so much easier. It is the only solution I've found so far that addresses all of the issues that I was ranting about earlier. Only thing is there is a slight delay when starting my tests as it's creating the in-memory database (it uses another package called NMemory to do this), but I don't see this as a real problem. There's a Code Project article that talks about using Effort (versus SQL CE) for testing.

share|improve this answer
3  
Any architecture article without mentioning unit test are automatically sent to the trash bin for me. One of the point of repository pattern is to gain some test-ability. –  Sleeper Smith Feb 19 '13 at 6:06
1  
You can still have unit tests without wrapping the EF Context (which is already a repository). You should be unit testing your domain / services not database queries (they're integration tests). –  Daniel Little Dec 3 '13 at 4:36
    
EF's testability has improved greatly in version 6. You may now fully mock DbContext. Regardless, you could always mock DbSet, and that's the meat of Entity Framework, anyways. DbContext is little more than a class to house your DbSet properties (repositories) in one location (unit of work), especially in a unit testing context, where all the database initialization and connection stuff is not wanted or needed anyways. –  Chris Pratt Mar 6 at 0:29

The reason why you probably would do that is because it's a little redundant. Entity Framework gives you a wealth of coding and functional advantages, that's why you use it, if you then take that and wrap it in a repository pattern you are throwing those advantages away, you might as well be using any other data access layer.

share|improve this answer

In theory I think it makes sense to encapsulate the database connection logic to make it more easily reusable, but as the link below argues, our modern frameworks essentially take care of this now.

Reconsidering the Repository Pattern

share|improve this answer
    
I liked the article , but IMHO for enterprise apps , the abstraction layer between DAL and Bl MUST Have feature , since you couldn't know what exactly will be used tomorrow. But thanks for sharing the link –  StringBuilder Dec 12 '12 at 21:15
1  
While personally I think it's true for e.g. NHibernate (ISessionFactory and ISession are easily mockable), it's not that easy with DbContext, unfortunately... –  Patryk Ćwiek Dec 28 '12 at 23:02

A very good reason to use the repository pattern is to allow the separation of your business logic and/or your UI from System.Data.Entity. There are numerous advantages to this, including real benefits in unit testing by allowing he use of Fakes or Mocks.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.