26

I am using ASP.NET MVC 2 and C# with Entity Framework 4.0 to code against a normalised SQL Server database. A part of my database structure contains a table of entries with foreign keys relating to sub-tables containing drivers, cars, engines, chassis etc.

I am following the Nerd Dinner tutorial which sets up a repository for dinners which is fair enough. Do I do one for drivers, one for engines, one for cars and so on or do I do one big one for entries?

Which is the best practise for this type of work? I am still new to this method of coding.

Ian Roke
  • 1,774
  • 1
  • 19
  • 27

4 Answers4

47

I guess there's really no single "best practice" for this - it depends on your coding style and the requirements for your app. You definitely could create a repository for each entity type in your system - that'll work just fine.

In your case here, I would probably at least consider having a repository for drivers, and possibly a second one for cars, engines, chassis (since those are kinda in the same area of expertise - they're interconnected, they "belong" together).

But: of course, if that single repository for cars, engine and chassis gets too bloated, you might consider breaking it up into three separate repositories.

I would try to find a balance between the number of repositories - try to group together what logically belongs together - and the number of methods on those repositories. Five, ten methods is okay - if you're talking 20, 30 or 50 methods, your repository might just be too big and unwieldy.

This is definitely an architectural decision, and as such, they're not really a lot of hard facts to guide you - it's more of a "gut feeling" and experience kind of thing. If you don't have that necessary experience yet - go with one approach, use it, and when you're done - look at it again with a critical eye and see: what worked about it? What about it didn't work? and then in your next project, try some other approach and question its validity, too, at the end of the project. Live and learn!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    Love when the experience talks. This is one the best easy-to-follow guides. Don't know if it is only because this is what I had in mind before looking for answer but still – Farid Sep 16 '22 at 14:25
21

Personally speaking, I find it best to create a separate repository for each table.

I then create a services layer where in one class I would run all the commands for a specific action (ex, change an already existing driver's car to a newly added car). The services layer is where I'll call multiple repository if an action I need done contains multiple objects that are interrelated.

I try my best to keep my repositories as "dumb" as possible and put all the "smart" stuff in the services layer. The extra services layer also helps me avoid bloating my controllers.

Omar
  • 39,496
  • 45
  • 145
  • 213
  • 1
    I like this approach, but another dev on my team mentioned there could be performance concerns if your service layer has to make 4-5 table calls to piece all the data it needs together. Is this a necessary evil or is there a tactic to mitigate this? – Hunter Nelson Aug 17 '17 at 13:50
  • This is a good point, what about when a JOIN makes far more sense? Your service layer would be far slower than using a JOIN on a database (in general)...? – John Hunt Nov 08 '17 at 16:37
  • 1
    What you're pointing out is where the strategy I mentioned does break down. At that point it might make sense to create a function specific repositories. That's not to say you have to move away from having a single repository per table, you can do both. – Omar Nov 08 '17 at 16:40
  • That's why you have Foreign Keys I think.Like this maybe you would not need joins inside Entity / Repository – user_1856538_ Apr 02 '18 at 17:03
8

I am using generic (parametrized) repository for every entity. This repository contains basic CRUD function. Above that I have service for every functionality. Every service instantiates needed repositories. ObjectContext is common for all of them and there is one for every request. This is my repository interface:

public interface IRepository<T>
{
    //Retrieves list of items in table
    IQueryable<T> List();
    IQueryable<T> List(params string[] includes);

    //Creates from detached item
    void Create(T item);
    void Delete(int id);
    T Get(int id);
    T Get(int id, params string[] includes);
    void SaveChanges();
}

I have also generic implementation, that is long, but easy to implement. You won't have to create repository class for every type, just instantiate Repository<Type>.

LukLed
  • 31,452
  • 17
  • 82
  • 107
  • And what about if I need to involve stored procedures as well ? Maybe there are some stored procedures that defines custom Insert or Delete (meaning to some extra stuff besides simply delete / insert) ... – user_1856538_ Apr 02 '18 at 17:00
  • Stored procedure repositories are independent from EF Core based repositories – Maulik Modi Dec 05 '21 at 11:42
6

I usually take the diagramm of the database and draw circles around what I consisder a bigger unit or system.

That gets me something like "ProductSystem" , "OrderSystem" , "UserSystem", "PaymentSystem" in a shop.

If systems get too big I devide them.

If systems are too little I dont care: Everything will grow anyway.

If something belongs in some way to 2 systems I choose 1 and dont change it anymore, even if the next day the decission seams wrong: I know that the day will come when I want to change it back again.

Mathias F
  • 15,906
  • 22
  • 89
  • 159