IQueryable interface
Translating a LINQ query to a SQL query
The IQueryable
and IQueryable<T>
interfaces allows developers to translate a LINQ query (a ‘language-integrated’ query) to a specific datasource, for example a relational database. Take this LINQ query written in C#:
var query = from book in books
where book.Author == "Stephen King"
select book;
If the variable books
is of a type that implements IQueryable<Book>
then the query above gets passed to the provider (set on the IQueryable.Provider
property) in the form of an expression tree, a data structure that reflects the structure of the code.
The provider can inspect the expression tree at runtime to determine:
- that there is a predicate for the
Author
property of theBook
class; - that the comparison method used is ‘equals’ (
==
); - that the value it should equal is
"Stephen King"
.
With this information the provider can translate the C# query to a SQL query at runtime and pass that query to a relational database to fetch only those books that match the predicate:
select *
from Books
where Author = 'Stephen King'
The provider gets called when the query
variable is iterated over (IQueryable
implements IEnumerable
).
(The provider used in this example would require some extra metadata to know which table to query and to know how to match properties of the C# class to columns of the table, but such metadata is outside of the scope of the IQueryable
interface.)