1) IQueryable essentially represents a query which when executed will yield a sequence of results.
a) I assume we execute query by either directly calling IQueryProvider.Execute ( immediate execution ) and passing in an expression tree or by calling IQueryable.GetEnumerator ( deffered execution )?
b) is it IQueryProvider.Execute that actually converts the expression tree into target language ( say SQL ) and then retrieves the results from a DB?
2)
public class Query<T> : IQueryable<T> ...
{
...
public IEnumerator<T> GetEnumerator()
{
return((IEnumerable<T>)this.provider.Execute(this.expression)).GetEnumerator();
}
}
Query<string> someQuery = new Query<string>();
foreach (var item in someQuery) { ... }
a) In the above example query is executed by foreach calling someQuery.GetEnumerator. I assume that in order for the query to actually get executed, the IQueryProvider.Execute must be called from within someQuery.GetEnumerator( via this.provider.Execute )?
Thank you
EDIT
1)
If the query is returned from a Queryable method, then it is deffered
until GetEnumerator() or Execute() is called.
I realize that queries returned from IQueryable are deffered, but it seems that you’re implying that queries ( those implementing IQueryable ) may also be returned from non-Queryable methods ( in which case they are not deffered )?
2)
This is how LINQ-to-SQL does it. LINQ-to-Entites, however, seems to
bypass IqueryProvider when GetEnumerator() is called since its
ObjectQuery provider already has the target implementation-specific
command tree ready to be executed.
I’ve just began learning Linq to entities, but it seems that ObjectQuery<> represents both a query and a specific provider, while with Linq-to-sql ( don’t know any Linq-to-sql, so I’m just guessing ) a query is represented with IQueryable<> and provider is represented with IQueryProvider?
1.a) An
IQueryable<T>query is usually executed by callingIEnumerable<T>.GetEnumerator()(more often than not via aforeachloop). You can useIQueryable.Execute()as well, which will also execute the query, but you’ll have to cast the result from theIExecuteResultobject that’s returned. If the query is returned from aQueryablemethod, then it is deffered untilGetEnumerator()orExecute()is called.1.b) Yes,
IQueryProvider.Executetakes an implementation-specificExpressionand converts it to the implementation-specific target form, and executes that code on the implementation backing (e.g., database or web service).2.a) This is how LINQ-to-SQL does it. LINQ-to-Entites, however, seems to bypass
IQueryProviderwhenGetEnumerator()is called since itsObjectQuery<T>provider already has the target implementation-specific command tree ready to be executed.