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
表示?
答案 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>
提供程序已经准备好执行特定于目标实现的命令树。