必须从IQueryable.GetEnumerator中调用IQueryProvider.Execute吗?

时间:2011-09-27 18:32:47

标签: linq

1)IQueryable基本上代表一个查询,在执行时将产生一系列结果。

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

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执行。我假设为了使查询实际执行,必须从IQueryProvider.Execute(通过someQuery.GetEnumerator)内调用this.provider.Execute

谢谢

修改

1)

  

如果从Queryable方法返回查询,则会对其进行修改   直到调用GetEnumerator()或Execute()。

我意识到从IQueryable返回的查询被修改了,但似乎您暗示查询(实现IQueryable的那些查询)也可以从非可查询方法返回(在这种情况下,它们没有被拒绝)?

2)

  

LINQ-to-SQL就是这样做的。然而,LINQ-to-Entites似乎也是如此   自从调用GetEnumerator()时绕过IqueryProvider   ObjectQuery提供程序已经具有特定于目标的实现   命令树准备好执行。

我刚刚开始向实体学习Linq,但似乎ObjectQuery<>代表查询和特定提供者,而使用Linq-to-sql(不知道任何Linq-to-sql,所以我只是猜测一个查询用IQueryable<>表示,提供者用IQueryProvider表示?

1 个答案:

答案 0 :(得分:2)

1.a) IQueryable<T>查询通常是通过调用IEnumerable<T>.GetEnumerator()执行的(通常通过foreach循环执行)。您也可以使用IQueryable.Execute(),它也将执行查询,但您必须从返回的IExecuteResult对象中转换结果。如果从Queryable方法返回查询,则会在调用GetEnumerator()Execute()之前将其保留。

1.b)是的,IQueryProvider.Execute采用特定于实现的Expression并将其转换为特定于实现的目标表单,并在实现支持上执行该代码(例如,数据库或Web服务)。

2.a)这就是LINQ-to-SQL的用法。但是,当调用IQueryProvider时,LINQ-to-Entites似乎绕过GetEnumerator(),因为它的ObjectQuery<T>提供程序已经准备好执行特定于目标实现的命令树。