20

Repository pattern is used to abstract from particular database and object-relation-mapping technology(like EF) used. So I can easily replace (for example) my Entity framework mappings with Linq to SQL in the future if I decide to do so.

But when I use EF I have my entity classes from the model - that is they are generated from that visual diagram. If I use this generated entity classes in my repository and then decide to replace EF by something else then I will delete that visual entity diagram and that means also to delete classes right ?

The point I'm addressing is that my repository will be dependent on Entity framework, that is on data access layer because it will use classes generated by EF.

How do I remove this dependency ?

Also note that I use EF primarily because of its ability to generate everything from that visual diagram - I just design the diagram and let it generate database for me with all the foreign keys etc. I like that very much and don't want to even think about SQL commands.

Rasto
  • 17,204
  • 47
  • 154
  • 245

4 Answers4

29

A repository is always dependent on data access technology. It is the reason why people are using repositories - to wrap data access dependency to separate layer. If you decide to change data access technology (imho it is like 1% chance that you do it) you will have to create new repositories implementing the same interfaces as former ones.

Introducing repositoris will add a new layer of complexity. Repositories have their pros and cons. Introducing them just because "you can change data access approach in the future" is a bad reason. Do not design your application because of something can happen. Design the application based on current real requirements (an agile way) and refactor your code if a change is needed - that is the only way how to be competitive in the market. Features are selling your SW not its open architecture for any type of change (ok, there are exceptions but in such cases that open architecture is a top level requirement).

When using EF you have several choices how to create entities:

  • Use cutom tool to generate Entity objects. This is default approach which creates "code behind" file for EDMX. It is the only available solution in EFv1 (.NET 3.5 SP1).
  • Use T4 templates to generate Entity objects, POCOs, STEs or any custom entity types (you can modify generation logic). This is often used with EFv4.
  • Write POCOs by yourselves. This can be used with EFv4 and it is always used with code first approach in EF 4.1.

If you expect that data access technolgy can change in the future use either the second or the third approach with POCOs. In the case of T4 templates you can simply copy generated POCOs or modify a project file so you will not lose them after deleting EDMX file.

If you are not sure if either second or third approach suits you check my answers to these questions:

Because I somehow agree with @Patko's answer you should also check Ayende's blog. He has written several posts about over using repository and over architecting applications. He is writting about NHibernate but similar decissions can be made with EF. The only difference is that NHibernate offers better abstraction so the code using directly NHibernate is better testable.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • @Ladislav Mrnka First I have to disagree with "Do not design your application because of something can happen". I always try to make my code robust and defensive and it usually proofs as good decision later. Few extra lines mean hours saved on refactoring and debugging. If "Do not design your application because of something can happen" was true not many projects would use repositories at all (except of those that need to support 2 persistent storage technologies right from the beginning). Second I just feel bad about passing reference to context to Service layer so I need some DAL to wrap it. – Rasto Mar 23 '11 at 09:05
  • @Ladislav Mrnka +1 for T4 templates and those links. Some more resources about that ? – Rasto Mar 23 '11 at 09:12
  • 1
    @drasto: If you are skilled enough to make professional decission about your architecture then the approach is ok. But after answering and reading many questions about EF and repositories I simply think that many developers are over architecting their applications. Having two data access technologies from the beginning is a good reason for introducing repositories but you didn't mention it in the question. – Ladislav Mrnka Mar 23 '11 at 09:15
  • @drasto: Just ask what information you are looking for and I will try to add some resources. – Ladislav Mrnka Mar 23 '11 at 09:16
  • @Ladislav Mrnka I'm not having 2 data access technologies from the beginning, that was just to say that if everybody takes your "Do not design your application because of something can happen" approach then only application that need repository would be probably those that need to support 2 data access technologies from the beginning. In the fact I don't expect a need to change data access technology any time soon. I just feel bad about passing `ObjectContext` instance to services in service layer... I think some intermediating DAL wrapping EF would by clearer(even if EF is kind of DAL too). – Rasto Mar 23 '11 at 09:24
  • 1
    @drasto I guess what Ladislav is trying to say, is that you need valid reasons to introduce the abstraction of a repository. If you don't want the dependency on EF in your Service Layer and you think the repository pattern will help you with that, it is a valid enough reason; there might be other solutions, but it's your choice. – Rodi Jun 23 '11 at 07:56
  • @Ladislav If nHibernate has better abstraction it might be ok for that, but one "rule" I like to use (from GOOS book) is "only mock types you own" and so I would introduce the abstraction even with nHibernate (as an adapter of sorts). (BTW you have some great posts and answers on EF and related objects; thanks for helping us newbies out) – Rodi Jun 23 '11 at 07:59
  • @LadislavMrnka many people and I are asking you to recommend or publish a step by step posts on how implement EF repository with some integration tests.We are no longer can distinguish best practices from bad ones. If any suggestions please get us in touch. Thanks – HichemSeeSharp Sep 06 '12 at 22:29
9

Having the ability to switch from one persistence techonology to another is nice and all, but do you really need it?

First of all, what is a repository? By Fowler's definition it provides an in-memory collection-like access to domain objects. But every modern ORM tool already does that, so another level of abstraction just adds a bit more complexity.

Second, switching from one persistence technology to another is usually more complex than just providing another repository implementation. For instance, how do you intend to handle transactions? Transactions usually depend on context and are handled outside repositories. You could of course use some kind of unit of work implementation, but then you would have to implement new unit of work for every persistence technology.

I do not mean to say that you should not use repositories, just maybe give it another thought.

Patko
  • 4,365
  • 1
  • 32
  • 27
  • I'm still considering my options. I have ASP.NET MVC application where persistence just want work... It is really bad designed. So I'll have to rebuild it from scratch this time properly and in the way that will allow me to easily change model according to developing business logic needs (that I'm working on right now). So what do you suggest I do ? Should I just pass instance of `ObjectContext` to services in service layer ? I feel somehow bad about that... – Rasto Mar 23 '11 at 09:14
  • 3
    +1 because I agree with it. Repository is overused and it was defined before any modern ORM tools existed. – Ladislav Mrnka Mar 23 '11 at 09:19
  • 3
    Maybe you can look at Ayende's blog at http://ayende.com/Blog/default.aspx. He was one of the proponents of the repository pattern, but he changed his mind. It started with this http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx blog post. His latest posts also provide some ideas as to how to do it. As to `ObjectContext`, I don't see why not. If you would pass repositories would it feel better? Just look at `ObjectContext` as a kind of repository :) – Patko Mar 23 '11 at 09:23
  • That does make sense. `ObjectContext` is kind of DAL itself. – Rasto Mar 23 '11 at 09:29
6

The entity classes created by EF's designer are there in your project, inside your "Model.Designer.cs". You can copy the code so that your entities remain on your project even if you remove your model or the references from EF. However, they are tightly coupled to EF, so you should strive for decoupling EF from your entity classes.

Until now, you had T4 templates that could help you with the decoupling, but they still would require some changes to the chosen T4:

  • ADO.NET EntityObject Generator
  • ADO.NET POCO Entity Generator
  • ADO.NET Self-Tracking Entity Generator

EF4.1 brings a simplified API, DbContext, that improves your experience with EF when you want to decouple entity classes. With EF4.1 you get 3 approaches:

  • Code First
    • you create the classes and EF creates the DB as it should be
    • classes won't go away when you remove references to EF
    • you won't have any designer
  • Database First
    • if you already have a database, a model will be created for you on the designer
    • you can create your entity classes with the new T4 template DbContext Generator
  • Model First
    • as you already do right now, you create your model in the designer
    • you can create entity classes with DbContext Generator

Now, answering your question:

How do I remove this dependency ?

  1. Install EF4.1
  2. Create your model (using Model-first approach)
  3. Generate your database from your model
  4. Generate your entity classes with DbContext Generator

See how you can do all this here: EF 4.1 Model & Database First Walkthrough.
You should read the series in ADO.NET Team Blog Using DbContext in EF Feature CTP5 Part 1: Introduction and Model (EF4.1 was formerly known as EF Feature CTP5).
You can get more details in my question: EF POCO code only VS EF POCO with Entity Data Model.

Community
  • 1
  • 1
Nelson Reis
  • 4,780
  • 9
  • 43
  • 61
  • +1 Right now you are the clear winner here. I was decided to use T4 templates to generate POCO entities and then try to figure out how to make the framework automatically recreate database tables when I change the model. But I like your suggestion more so far - it looks like it is easier to do it with simplified API then with T4 templates. I have one more question: Is it possible to have my database tables to be automatically recreated together with POCO classes every time I change my model when using Model First approach ? How can I do it ? – Rasto Mar 23 '11 at 18:32
  • I know automatic tables generation is possible for code first approach – Rasto Mar 23 '11 at 18:40
  • I have asked another question that was inspired by your answer here, please feel free to post some answer http://stackoverflow.com/questions/5410381/generate-poco-classes-from-model-using-t4-templates-vs-ef4-1-simplified-api-mode . Thank you anyway – Rasto Mar 23 '11 at 19:28
  • @drasto You can recreate your database manually when you change your model. Just delete your database and regenerate it. However, you will also loose any test data you could have. As you said above, with code first, it is possible to automatic generate and seed your database: http://thedatafarm.com/blog/data-access/seeding-a-database-with-ef4-code-first/ – Nelson Reis Mar 24 '11 at 09:51
3

One of the new features in Entity Framework version 4 is "Code First" development. This will allow you to use regular C# (POCO) classes with entity framework. Once your classes are written this way, you could write a different implementation of the repository that persists those classes using a different mechanism.

ScottGu has a blog post containing more information.

Sean Reilly
  • 21,526
  • 4
  • 48
  • 62
  • 1
    Actually it is not the feature of EFv4. It is separate version called EF 4.1. – Ladislav Mrnka Mar 23 '11 at 08:11
  • +1 I like it. Not only because having independent classes but also because of the ability recreate databases whenever I make change to model classes. However there is something I don't like - that is having to write all the classes and their properties - I expect my model to have around 50-70 classes. In visual designer it looks much better. So I was hoping for something like "1. create visual model diagram 2. have VS generate POCO classes from the diagram 3. Have EF to generate tables foreign key etc from POCO classes or(even better)have some other tool generate EF diagram from POCO clases" – Rasto Mar 23 '11 at 08:27
  • @drasto - A common critisism with EF's designer is the how unwieldy it is to use with a good amount of entities. Weird that you have the opposite issue. @Sean Reily - Your answer is incorrect. "Code First" in 4.1 did not enable you to use POCO classes, this was possible out of the box in 4.0. MS later released t4 templates which made this easier. http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313 – John Farrell Mar 23 '11 at 12:31
  • @jfar - I said 4.0 (quoting ScottGu). Others mentioned 4.1. – Sean Reilly Mar 24 '11 at 09:30
  • in EF 4.0 you can use POCOs, however, if you do not generate the conceptual model and mapping via code, it is not considered code-first. – Danny Varod Mar 28 '11 at 16:36