日期:2011-04-28 浏览次数:20520 次
原文:《C# Version 3.0 Specification》,Microsoft
翻译:lover_P
查询表达式(Query Expression)为查询提供了一种语言集成的语法,这种语法类似于关系和分级查询语言,如SQL和XQuery。
query-expression:
from-clause query-body
from-clause:
from from-generators
from-generators:
from-generator
from-generators , from-generator
from-generator:
identifier in expression
query-body:
from-or-where-clausesopt orderby-caluseopt select-or-group-clause into-clauseopt
from-or-where-clauses:
from-or-where-clause
from-or-where-clauses from-or-where-clause
from-or-where-clause:
from-clause
where-clause
where-clause:
where boolean-expression
orderby-clause:
orderby ordering-clauses
ordering-clauses:
ordering-clause
ordering-clauses , ordering-clause
ordering-clause:
expression ordering-directionopt
ordering-direction:
ascending
descending
select-or-group-clause:
select-clause
group-clause
select-clause:
selelct expression
group-clause:
group expression by expression
into-clause:
into identifier query-body
一个查询表达式以一个from子句开始,以一个select或group子句结束。起始的from子句后可以跟零个或多个from或where子句。每个from子句都是一个生成器,该生成器引入了一个可以覆盖整个序列的迭代变量;而每个where子句都是一个过滤器,该过滤器用于从结果中排出项目。最终的select或group子句根据迭代变量来指定结果的表现形式。select或group子句前面还可以有一个orderby子句,用以指定结果的顺序。最后,可以用一个into子句通过将一个查询的结果作为一个子查询的生成器来“联结”两个查询。
在查询表达式中,具有多个生成器的from子句严格等价于多个顺序的只具有一个生成器的from子句。
7.1 查询表达式的翻译
C# 3.0语言并没有为查询表达式指定确切的执行语义,而是将查询表达式翻译为对附着于查询表达式模式(Query Expression Pattern)的方法的调用。特别地,查询表达式分别被翻译为对名为Where、Select、SelectMany、OrderBy、OrderByDescending、ThenBy、ThenByDescending和GroupBy的方法的调用,这些方法有着预期的签名和返回值类型。这些方法既可以是待查询对象的实例方法,也可以是对象外部的扩展方法。这些方法进行着实际的查询工作。
将查询表达式翻译为方法调用的过程是一个语法映射过程,发生在任何类型绑定或重载抉择的执行之前。翻译的结果可以保证语法正确,但不一定保证产生语义正确的C#代码。在查询表达式翻译之后,产生的方法调用作为一般的方法调用进行处理,这时会依次发现错误,如方法不存在、参数类型错误或对一个范型方法的类型推断失败等。
后面的一系列示例依次演示了查询表达式的翻译。在后面的某一节中给出了翻译规则的正式描述。
7.1.1 where子句
查询表达式中的一个where子句:
from c in customers
where c.City == "London"
select c
将被翻译为对一个Where方法的调用,其参数为合并了迭代变量和where子句中的表达式所得到的拉姆达表达式:
customers.
Where(c => c.City == "London")
7.1.2 select子句
上面的例子演示了选择了最内部的迭代变量的select子句是如何通过翻译为方法调用被消除的。
一个选择了并非最内部的迭代变量的select子句:
from c in customers
where c.City == "Longdon"
select c.Name
将被翻译为一个Select方法调用,其参数是一个拉姆达表达式:
customers.
Where(c => c.City == "London").
Select(c => c.Name)
7.1.3 group子句
一个group子句:
from c in customers
group c.Name by c.Country
将被翻译为对GroupBy方法的调用:
customers.