C# 回顾之 查询表达式

时间:2020-01-05 17:11:18   收藏:0   阅读:150

1. 查询表达式

查询表达式 (query expression) 为查询提供一种类似于关系和分层查询语言(如 SQL 和 XQuery)的语言集成语法。

  1. 初始 from 子句后面可以跟零个或者多个 from、let、where、join 或 orderby 子句。
  2. 每个 from 子句都是一个生成器,该生成器将引入一个包括序列 (sequence) 的元素的范围变量 (range variable)。
  3. 每个 let 子句都会引入一个范围变量,以表示通过前一个范围变量计算的值。
  4. 每个 where 子句都是一个筛选器,用于从结果中排除项。
  5. 每个 join 子句都将指定的源序列键与其他序列的键进行比较,以产生匹配对。
  6. 每个 orderby 子句都会根据指定的条件对各项进行重新排序。而最后的 select 或 group 子句根据范围变量来指定结果的表现形式。
  7. 最后,可以使用 into 子句来“连接”查询,方法是将某一查询的结果视为后续查询的生成器。

2. 分类

  1. query-expression

    from-clause query-body

  2. from-clause

    from typeopt identifier in expression

  3. query-body

    query-body-clausesopt select-or-group-clause query-continuationopt

  4. query-body-clauses

    1. query-body-clause
    2. query-body-clauses query-body-clause
  5. query-body-clause

    1. from-clause
    2. let-clause
    3. where-clause
    4. join-clause
    5. join-into-clause
    6. orderby-clause
  6. let-clause

    let identifier = expression

  7. where-clause

    where boolean-expression

  8. join-clause

    join typeopt identifier in expression on expression equals expression

  9. join-into-clause

    join typeopt identifier in expression on expression equals expression into identifier

  10. orderby-clause

    orderby orderings

  11. orderings

    1. ordering
    2. ordering,ordering
  12. ordering-direction

    1. ascending
    2. descending
  13. select-or-group-clause

    1. select-clause
    2. group-clause
  14. select-clause

    select expression

  15. group-clause

    group expression by expression

  16. query-continuation

    into identifier query-body

3. 多义性

  1. 查询表达式上下文关键字:from、where、join、on、equals、into、let、orderby、ascending、descending、select、group 和 by。
  2. 查询表达式是以“from identifier”开头后接除“;”、“=”或“,”之外的任何标记的任何表达式。
  3. 如果要使用关键字作为简单名称使用,在其前缀上加上“@select”

4. 转换

C# 语言不指定查询表达式的执行语义。而是将查询表达式转换为遵循查询表达式模式的方法调用。具体而言,查询表达式将转换为对具有以下名称的方法的调用:Where、Select、SelectMany、Join、GroupJoin、OrderBy、OrderByDescending、ThenBy、ThenByDescending、GroupBy 和 Cast。

4.1 转换规则

  1. 从查询表达式到方法调用的转换是一种句法映射,在执行任何类型绑定或重载决策之前发生。
  2. 查询表达式的处理方式为:重复应用以下转换,直到不可能进一步缩减。
  3. 转换按应用顺序列出:每一部分都假设前面部分的转换已彻底执行,一旦某个部分彻底执行,之后在同一查询表达式的处理过程中便不再重新访问该部分。
  4. 不允许对查询表达式中的范围变量进行赋值。但允许 C# 实现在某些时候可以不实施此限制,因为对于此处介绍的句法转换方案,有些时候可能根本无法实施此限制。
  5. 某些转换使用由 * 指示的透明标识符注入范围变量。

4.2 转换示例

1. 带继续符的查询表达式

2. 显示范围变量类型

显式范围变量类型对于查询实现非泛型 IEnumerable 接口的集合很有用,但对于实现泛型 IEnumerable 接口的集合没什么用处。

3. 退化查询表达式

退化查询表达式是平常选择源的元素的查询表达式。后面的转换阶段会移除由其他转换步骤引入的退化查询,方法是用其源替换这些退化查询。

from x in e select x 转换为 ( e ) . Select ( x => x )
from c in customers select c 转换为 customers.Select(c=>c)

4. from、let、where、join和orderby子句

5. 示例

6. select子句

from x in e select v
转换为
( e ) . Select ( x => v )

当 v 为标识符 x 时,转换仅为
( e )

from c in customers.Where(c => c.City == “London”)
select c
仅转换为
customers.Where(c => c.City == “London”)

7. groupby子句

from x in e group v by k
转换为
( e ) . GroupBy ( x => k , x => v )

当 v 为标识符 x 时,转换为
( e ) . GroupBy ( x => k )

from c in customers
group c.Name by c.Country
转换为
customers.
GroupBy(c => c.Country, c => c.Name)

8. 透明标识符

  1. 某些转换使用由 * 指示的透明标识符注入范围变量。透明标识符不是合适的语言功能;它们在查询表达式转换过程中仅作为中间步骤存在。
  2. 当查询转换注入透明标识符时,进一步的转换步骤将透明标识符传播到匿名函数和匿名对象初始值设定项中。
  3. 透明标识符始终与匿名类型一起引入,目的是以一个对象的成员的形式捕获多个范围变量。

5.模式

查询表达式模式 (Query expression pattern) 建立了一种方法模式,类型可以实现该模式来支持查询表达式。因为查询表达式通过句法映射转换为方法调用,所以类型在如何实现查询表达式模式方面具有很大灵活性。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!