开发者

Must IQueryProvider.Execute be called from within IQueryable.GetEnumerator?

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.Ex开发者_如何学Pythonecute ( 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 calling IEnumerable<T>.GetEnumerator() (more often than not via a foreach loop). You can use IQueryable.Execute() as well, which will also execute the query, but you'll have to cast the result from the IExecuteResult object that's returned. If the query is returned from a Queryable method, then it is deffered until GetEnumerator() or Execute() is called.

1.b) Yes, IQueryProvider.Execute takes an implementation-specific Expression and 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 IQueryProvider when GetEnumerator() is called since its ObjectQuery<T> provider already has the target implementation-specific command tree ready to be executed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜