Tuesday 20 October 2009

IQueryable and IQueryable<T>

The type returned from a LINQ query will be of type IQueryable. For example, the var in the following query will be an IQueryable:
var query = from u in data.Users 
            where u.LastName == "Smith" 
            select new { u.FirstName, u.LastName}
IQueryable has very few members and has 3 properties of particular interest:
public interface IQueryable : IEnumerable
{
    Type ElementType { get; }
    Expression Expression { get; }
    IQueryProvider Provider { get; }
}
An IQueryable has an Expression property. In other words we can get hold of the Expression Tree for the query (note that the Expression type is the base class for the open generic implementations such as Expression<T>). If we can get hold of the Expression Tree we can manipulate it!
Because IQueryable has a GetEnumerator() method you can enumerate the results of the query. 
See http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx
IQueryable<T> implements IQueryable (which itself implements IEnumerable) and “provides functionality to evaluate queries against a specific data source wherein the type of the data is known”. The MSDN documentation states:
“This interface inherits the IEnumerable<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<T> object to be executed. Queries that do not return enumerable results are executed when the Execute<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<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.” (my italics)
IQueryable<T> has a stack of members including all the query type operations you would expect in the form of extension methods (e.g.  Distinct, Max, Min, etc). It has the same properties as IQueryable, including the Expression property.
See http://msdn.microsoft.com/en-us/library/bb337580.aspx