查询表达式是C#3.0中添加的一种新语法。查询表达式和SQL风格非常相近的语法,使用查询表达式可以将许多查询操作符转换成更容易理解的代码。
1、查询表达式概述
查询表达式包括以下子句:
- from子句:指定查询操作的数据源和范围变量
- where子句:指定拆选元素的逻辑条件
- select子句:指定查询结果的类型和表现形式
- orderby子句:对查询结果进行排序操作,包括升序和降序
1.1 筛选和投射
static main()
{
IEnumerable<string> fileNames = Directory.GetFiles(root, search);
IEnumerable<FileInfo> fileInfos =
from name in fileNames
where name.Contains("*.txt")
select new FileInfo(name);
}
编译器可以通过from子句推导出“输入”的类型,而通过select子句或groupby子句推导出“输出”的类型。查询表达式的select子句可以将from子句的表达式所收集到的东西投射到其他数据类型。
1.2 排序
static main()
{
IEnumerable<string> fileNames = Directory.GetFiles(root, search);
IEnumerable<FileInfo> orderFileNames =
from name in fileNames
orderby new FileInfo(name).Length descending, name
select FileInfo(name);
}
orderby子句用于排序,子句后跟排序条件,如有多个条件则用逗号分割。descending和ascending分别指定以升序或降序排序,没有指定则默认是ascending。
1.3 let子句
static main()
{
IEnumerable<string> IEnumerable<string> fileNames = Directory.GetFiles(root, search);
IEnumerable<string> orderFileNames =
from name in fileNames
let file = new FileInfo(name)
orderby new file .Length descending, name
select file ;
}
let子句引入一个新的范围变量,它容纳的表达式值可以在查询表达式剩余的部分使用。可添加任意数量的let表达式,只需把它们每个作为一个附加的子句,放在from子句之后、selectgroupby子句之前。
1.4 分组
static main()
{
static string[] keywords = {"add*", "as", "async", "base", "break", "by*", "class", "const"};
IEnumerable<IGrouping<bool, string>> selection =
from word in keywords
group word by word.Contains('*')
}
groupby分组的结果是一系列IGrouping<TKey, TElement>类型的元素。Key的类型是by关键字后面的分组依据(上例中的word.Contains('*')),Value的类型是Group关键字后面的分组元素(上例中的word)。
1.5 查询延续
static main()
{
static string[] keywords = {"add*", "as", "async", "base", "break", "by*", "class", "const"};
var selection =
from word in keywords
group word by word.Contains('*')
into groups
select new
{
IsContextualKeyword= groups.Key,
Items = groups
};
}
into子句的作用是一个查询的输出,做为另一个查询的输入。into子句引入的范围变量(上例中的groups)作为查询剩余部分的范围范围变量。
2、查询表达式作为方法调用
查询表达式由编译器转换为方法调用。
private static void ShowContextualKeywords()
{
IEnumerable<string> selection =
from work in Keywords
where word.Contains('*')
select word
}
编译后,以上代码会被转换成System.Linq.Enumerable提供的IEnumerable<T>的扩展方法。将查询表达式转换为标准查询操作符语法,转换后的代码如下:
private static void ShowContextualKeywords2()
{
IEnumerable<string> selection = Keywords.Where(word => word.Contains('*'));
}