Wednesday 7 October 2009

The IQueryable<T> interface

The MSDN documentation states that it:

“Provides functionality to evaluate queries against a specific data source wherein the type of the data is known…

The IQueryable<(Of <(T>)>) interface is intended for implementation by query providers.

This interface inherits the IEnumerable<(Of <(T>)>) interface so that if it represents a query, the results of that query can be enumerated. Enumeration forces the expression tree associated with an IQueryable<(Of <(T>)>) object to be executed. Queries that do not return enumerable results are executed when the Execute<(Of <(TResult>)>)(Expression) method is called.

The definition of "executing an expression tree" is specific to a query provider. For example, it may involve translating the expression tree to a query language appropriate for an underlying data source.

The IQueryable<(Of <(T>)>) interface enables queries to be polymorphic. That is, because a query against an IQueryable data source is represented as an expression tree, it can be executed against different types of data sources.”

IQueryable<T> appears to be an excellent choice as a return type for repository methods. Because it is the enumeration that forces the execution of the expression tree the actual database query is deferred until that point. By passing IQueryable<T> around we can add to the query at any point and only execute it when the result is enumerated.

However, there is a down side. If we return an IQueryable<T> we are not really returning the data but rather a query that can be used to get the data. This is not what repositories are intended to do – the repository should execute the query and return the data, not return queries which can be used to get the data at some indeterminate point.

I think the jury is still out on this one.

Wednesday 7 October 2009