9

In my asp.net mvc 3 application, I'm using the repository pattern. I have 3 entities, Company, Country, City. Each of them has their own repository. Company entity has FoundedCountry and FoundedCity foreign keys. Now in a view, I want to show the company details. In this view I want to view Company details as well as, FoundedCountry name and FoundedCity name. In my opinion I have to handle this with a kind of JOIN query. But I'm stuck at how to achieve this in repository pattern. How can I handle this JOIN in repository pattern?

Thank you.

SherleyDev
  • 335
  • 5
  • 21

2 Answers2

6

The repository should have a task-based interface. This means that ORM's, joins etc are inside the repository. The app just sees an interface whtch returns an object that it can use.

This means you don't create a repository around a table (it pretty much defeats the purpose). In your scenario I suggest you have (at least) 2 repositories: one will handle everything related to updating the model and the other will serve only reads (queries).

This means the query repository will return only the data you want (it basically returns view model bits). Of course, the actual tables and joins are an implementation detail of the repository.

MikeSW
  • 16,140
  • 3
  • 39
  • 53
  • "This means you don't create a repository around a table (it pretty much defeats the purpose)." As far as I know, I have to create a repository for each entity. From your comment, I think I have to add another repository which will handle complex queries. Right? – SherleyDev Apr 24 '12 at 12:04
  • No :) . You don't 'have to' create a repository for each entity. The repository basically hides everything database related from the rest of the app. Inside the repository you might use entities, EF or Nhibernate, it doesn't matter. The repositoryu uses internally the orm, in your case the entities and then returns objects that the app understands. The entities themselves are already an abstraction used by the repository. – MikeSW Apr 24 '12 at 12:14
  • In the following tutorial it says "In this tutorial you'll implement a repository class for each entity type." I was following it. http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application – SherleyDev Apr 24 '12 at 12:16
  • 3
    Yes, that EF tutorial is wrong concerning the pattern (and I saw some other awkward decisions too). Its purpose is to push EF, not to teach you about the repository pattern. Many times the use of the repository is quite artificial. The repository is a very good pattern and I'm using it on every project, but not like this. And beware of the Generic Repository as well, it has very specific applicability, for most cases is an anti pattern though. I will post a bit of constructive criticism there too. – MikeSW Apr 24 '12 at 13:04
  • Thank you Mike. You enlightened me. – SherleyDev Apr 24 '12 at 13:27
3

Don't construct your repository pattern in a way that is preventing joins! This usually means to use the same ORM context (DataContext/ObjectContext) for all instances associated with the current HTTP request.

I consider it to be an anti-pattern to have a generic IRepository because database access is rarely constrained to a single type of entity at the same time.

You could consider the DataContext/ObjectContext to be a repository by itself.

A last advice: If you don't know what a repository abstraction is good for - don't use one.

usr
  • 168,620
  • 35
  • 240
  • 369
  • I disagree with one thing: that the Data Context should be considered as a repository. While the DC abstracts the db access and sql, it's still tied up with a rdbms and IMO it's a leaky abstraction at best. – MikeSW Apr 24 '12 at 10:09
  • If an ORM is a leaky abstraction, how leaky is a custom repository then? It is a sieve. At the same time it prevents you from accessing the full power of the ORM (which is the nature of an abstraction). – usr Apr 24 '12 at 10:16
  • 1
    A properly designed repository is not leaky because it doesn't expose implementation details such as an ORM. The repository does use the full power of the ORM, it's its job, It is not the job of the rest of the app to know about or to use the orm. Please see this post http://www.sapiensworks.com/blog/post/2012/04/15/The-Repository-Pattern-Vs-ORM.aspx – MikeSW Apr 24 '12 at 11:06