2011-09-27 82 views
1

1)IQueryable实质上代表一个查询,当执行时将产生一系列结果。必须从IQueryable.GetEnumerator中调用IQueryProvider.Execute吗?

a)我假设我们通过直接调用IQueryProvider.Execute(立即执行)并传入表达式树或通过调用IQueryable.GetEnumerator(执行执行)来执行查询?

b)是否IQueryProvider.Execute实际上将表达式树转换为目标语言(比如SQL),然后从数据库中检索结果?

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)在上面的例子中查询由调用的foreach执行someQuery.GetEnumerator。我假设为了使查询实际执行,必须从someQuery.GetEnumerator(通过this.provider.Execute)调用IQueryProvider.Execute

谢谢

编辑

1)

如果查询从可查询的方法返回,则递延 到的GetEnumerator()或执行()被调用。

我意识到查询从IQueryable返回的递延,但似乎你暗示的查询(那些实施IQueryable)也可以从非可查询的方法(在这种情况下,他们不递延)退还?

2)

这是如何LINQ到SQL做的。但是,由于其 ObjectQuery提供程序已具有准备执行的目标实现特定的 命令树,因此在调用GetEnumerator()时,似乎LINQ到实体 绕过了IqueryProvider。

我刚开始学习LINQ到实体,但似乎ObjectQuery<>既是一个查询和一个特定的供应商,同时与LINQ到SQL(不知道任何的LINQ到SQL,所以我只是猜测)查询用IQueryable<>代表,提供者用IQueryProvider代表?

回答

2

1.A)IQueryable<T>查询通常是通过经由foreach循环调用IEnumerable<T>.GetEnumerator()(往往不是)执行。您也可以使用IQueryable.Execute(),它也会执行查询,但您必须从返回的IExecuteResult对象中投出结果。如果查询是从Queryable方法返回的,那么它将被调用,直到调用GetEnumerator()Execute()

1.B)是,IQueryProvider.Execute需要一个实现特定Expression并将其转换为特定于实现的目标表,并执行该实现背衬代码(例如,数据库或Web服务)。

2.a)这就是LINQ到SQL的做法。然而,当调用GetEnumerator()时,LINQ到实体似乎绕过IQueryProvider,因为它的提供者已经准备好执行目标实现特定的命令树。

+0

你能看到我的编辑? – user702769

+1

__1)__我的意思是在理论上或技术上,可以实现预执行的非标准查询。 __2)__'IQueryable '和'IQueryProvider'都是LINQ标准接口。 'IQueryable'('IQueryable '继承)需要'IQueryProvider'作为其'Provider'属性。实际上LINQ-to-SQL的'表'实现了'IQueryable'和'IQueryProvider'。对于实体,一个单独的类ObjectQueryProvider(内部)用于IQueryProvider。 –

+0

非常感谢 – user702769

相关问题