Question

I am working on a project using ASP.NET MVC, and repository model. I have repository classes, and services which consume these repository classes. My question is: Is it correct to return a IQueryable from my repository class and then use ".Where" and ".OrderBy" in a Service to generate a List? If yes, is it the best practice?

Thanks!

Was it helpful?

Solution

For starters: there's no "right" or "wrong" here. It's just a matter of what works best for you and the system you are building. For example, Rob Conery did an ASP.NET sample application called Storefront with exactly the pattern you're describing and it ignited a big flame war. A large part of the discussion evolved around the Repository pattern that is considered the "original one" as described by Eric Evans in his book Domain Driven Design and that describes the interface of a repository as one that accepts and/or returns actual instances (of lists of instances) and not some query interface.

So much for theory. What to choose for your system? The reason I would not directly choose the IQueryable route is that it actually leaks a bit of my persistence strategy to the client layer (being the service layer in this case). Since it primarily makes sense to return an IQueryable if you're retrieving objects from the database using LINQ to [a database access method (like SQL, Entities, ...)]. Only then will .Where or .OrderBy be optimizing your query result. It obviously doesn't make sense if you're using some database access code code that gets a full list which you then expose from the Repository using LINQ to Objects. So in short: you do tie your client layer into the LINQ-based database access strategy you're using.

Being a bit of a purist myself, I would prefer not to surface this tie to LINQ from out of my repository, and I would choose to offer where- and order-by criteria through the parameters of the operations of the repository. I can do all the retrieval optimization in the repository and return a neat clean set of domain objects.

So in the end it comes down to: whatever works best for you is fine.

OTHER TIPS

I don't see why that would be an issue. If you're going to become more specific in the data you will be retrieving in your service layer, that means less data being transferred between the application and the database - which means higher efficiency. Doing so means you will also be implementing lazy loading, or getting the data when you absolutely need it. Considering the statelessness of the web, this is a good thing. You don't want to be retrieving all the data in case you might use it.

In other words, there's no sense in getting the entire list of users, to simply select the one who's name is "Jackolantern."

The best way to think of it is like so -- if you decide to switch from MSSQL to MySQL tomorrow, will you have to replicate business logic? If so, then you're utilizing your repository incorrectly.

Yes, I'm pretty happy with the repository returning IQueryable, but with one caveat: a few Linq functions aren't available across all providers. For example, the Single / SingleOrDefault methods aren't available in Linq to Entities. So your service layer may have to jump through some hoops depending on which concrete implementation of your repository is used.

I usually put the interface of the repository classes in the domain layer and the actual implementations in the service layer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top