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.

Using the Repository pattern, is it proper to return an IQueryable of a data set (table), for generic usage?

It is very handy in many cases, especially when using external libraries that leverage that interface, for example some plugins that sort/filter and bind to ui elements.

However, exposing an IQueryable sometimes seems to leave the design prone to errors. This, coupled with a wrong usage of lazy loading could lead to severe performance hits.

On the other hand, having access methods for every single usage seems redundant and also a lot of work (considering unit tests etc).

share|improve this question
2  
IMO : Hiding persistence technology (EF, NHibernate) from developers is bad idea. Just expose what this technology exposes. –  Euphoric Aug 27 '12 at 8:19

2 Answers 2

Mark Seemann has an excellent blog post about this subject: IQueryable is Tight Coupling. He sums it up nicely in the final part (emphasis mine):

You may think this is all a theoretical exercise, but it actually does matter. When writing Clean Code, it's important to design an API in such a way that it's clear what it does.

An interface like this makes false guarantees:

public interface IRepository
{
    IQueryable<T> Query<T>();
}

According to the LSP and Postel's law, it would seem to guarantee that you can write any query expression (no matter how complex) against the returned instance, and it would always work.

In practice, this is never going to happen.

Programmers who define such interfaces invariably have a specific ORM in mind, and they implicitly tend to stay within the bounds they know are safe for that specific ORM. This is a leaky abstraction.

If you have a specific ORM in mind, then be explicit about it. Don't hide it behind an interface. It creates the illusion that you can replace one implementation with another. In practice, that's impossible. Imagine attempting to provide an implementation over an Event Store.

The cake is a lie.

ORM's like Entity Framework are implementations of the Repository and the Unit of Work pattern. There's no need to wrap them in another one.

share|improve this answer
    
Thanks for the reply. Seems that my concerns meet those of Seemann's many times, but I havent actually taken the time to read him, which I intend to. The only thing I disagree with is that a repository -even if strongly coupled- is very useful to encapsulate business logic, even if at a simpler access level (ie: VisibleItems, DeletedItems) etc, and help with DRY concept. –  Mihalis Bagos Aug 28 '12 at 12:08

There will be no consensus on this one. In my opinion and experience, a Repository should return objects with specific uses. At leas if you use Repository Pattern as defined by Eric Evens in DDD. A Repository is a "bridge" connecting business logic, persistence and factories.

If you would like access to persistence more directly, maybe you are looking for the Gateway Pattern.

However, from what you say here, you would like to hide that exposure to persistence so the Proxy Pattern may com in handy for you.

share|improve this answer
    
While exposure to persistence is not a primary concern, at least a top level abstraction for patterns like parent-child entities is mandatory. I will look into those patterns also, thank you! –  Mihalis Bagos Aug 28 '12 at 12:12

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.