Monday, February 25, 2013

Exposing IQueryable from a Repository

During my hiatus of 2-1/2 years from this blog, I have gone from independent consulting through being employed by a large company to now working for small company. Along the way, I have picked up C#, .NET and other interesting artifacts of the computing world. For that reason, I am expanding my blog to cover not just Java, but any computing topics that sparks my interest at that moment.

Recently, I was asked for my opinion on this C#/LINQ subject: Are there is any downside to returning IQueryable from a Get in a Repository pattern? That question forced me to put my thoughts on the subject in order, which I am setting down here.

Now, I know that purists hate it because it violates the “Separation of Concerns” principle. And there are good (and practical) reasons to be wary:
  • Since IQueryable is an expression container, the programmer may potentially construct an ill-advised query (e.g., adding a filter on an un-indexed field or pulling in a large table in its entirety.)
  • It may make it harder to unit test since IQueryable has a trail leading all the way to the database. This may be alleviated by mocking the data source, but may not produce the same results.
On the other hand, there is also a huge upside, if you need it:
  • Paging. Because you are deferring execution to the database, you can let the database pull in only the exact number of records you need at the point where you need it – in the Controller. Much more efficient than pulling it all into memory and then paging in code. I’d argue that this, in fact, promotes the SoC principle by keeping paging in View-Controller where it properly belongs, instead of passing it along through the business layer into the repository for handling. (One way around this is to encapsulate IQueryable. I am not particularly keen on this but I can't quite put my finger on why.)
Looking on the web, it looks like I may be late to the game as this topic has been argued many times with people's opinions falling on both sides.


No comments:

Post a Comment