以下文章摘自博客园life a poem 的博客
书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询语法(Query Expression)。
LINQ方法语法是非常灵活和重要的,我们在这里将描述使用链接查询运算符的方式来创建复杂的查询,方法语法的本质是通过扩展方法和Lambda表达式来创建查询。C# 3.0对于LINQ表达式还引入了声明式的查询语法,通过查询语法写出的查询比较类似于SQL查询。本篇会对LINQ方法语法进行详细的介绍。
当然,.NET公共语言运行库(CLR)并不具有查询语法的概念。所以,编译器会在程序编译时把查询表达式转换为方法语法,即对扩展方法的调用。所以使用方法语法会让我们更加接近和了解LINQ的实现和本质,并且一些查询只能表示为方法调用,如检索序列中的最大值、最小值元素的查询,他们在查询语法中就没有对应的实现。但另一方面,查询语法通常会比较简单和易读。不管怎样,这两种语法和互相补充和兼容的,我们可以在一个查询中混合使用方法语法和查询语法。
链接查询运算符
static void Main(string[] args)
{
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> query = names
.Where(n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select(n => n.ToUpper());
foreach (string name in query) Console.WriteLine(name);
}
// Result:
JAY
MARY
HARRY
就像在本例中所示,当链接使用查询运算符时,一个运算符的输出sequence会成为下一个运算符的输入sequence,其结果形成了一个sequence的传输链,如图所示:
图:链接查询运算符
Where, OrderyBy, Select这些标准查询运算符对应Enumerable类中的相应扩展方法。Where产生一个经过过滤的sequence;OrderBy生成输入sequence的排序版本;Select得到的序列中的每个元素都经过了给定lambda表达式的转换。
下面是Where, OrderBy, Select这几个扩展方法的签名:
public static IEnumerable<TSource> Where<TSource>
(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
public static IEnumerable<TSource> OrderBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
public static IEnumerable<TResult> Select<TSource, TResult>
(this IEnumerable<TSource> source, Func<TSource, TResult> selector)