LINQ学习笔记:选取Select
选取
Select:使用给定的Lambda表达式转换每一个输入元素,对应SQL语法也是Select
SelectMany:转换输入元素, 然后连接各个结果子序列,对应SQL语法是INNER JOIN, LEFT OUTER JOIN, CORSS JOIN
对于LINQ to SQL查询, Select和SelectMany是最常用的连接构造方法, 而对于本地查询, Join和GroupJoin才是最有效的连接构造方法.
Select
参数列表:
源序列: IEnumerable
结果选择器: TSource => TResult或者(TSource,int) => TResult(LINQ to SQL不支持)
使用Select,你总是得到开始操作前相同的元素数量, 然而每一个元素是可以被任何数量的Lambda函数转换的.
以下的操作列出了电脑中安装的所有字体名称(来自于System.Drawing)
1: IEnumerable<string> query =
2:
3: from f in FontFamily.Families
4:
5: select f.Name;
6:
7: foreach (string name in query) Console.WriteLine (name);
在这个例子当中,select从句将一个FontFamily对象转换为它的名称.以下给出了一个相应的Lamdba表达式:
1: IEnumerable<string> query =
2:
3: FontFamily.Families.Select (f => f.Name);
Select语句经常与匿名类型一起使用:
1: var query =
2: from f in FontFamily.Families
3: select new
4: {
5: f.Name,
6: LineSpacing = f.GetLineSpacing (FontStyle.Bold)
7: };
有时,一个不含任何转换的选取会用于一个复合查询,并以select或者group语句作为结尾. 以下查询选择的字体都支持strikeout:
1: IEnumerable query =
2:
3: from f in FontFamily.Families
4:
5: where f.IsStyleAvailable (FontStyle.Strikeout)
6:
7: select f;
8:
9:
10:
11: foreach (FontFamily ff in query)
12:
13: Console.WriteLine (ff.Name);
索引选取
选择表达式可以接受一个可选的整数参数,这个参数指示输入序列中的每个元素的索引位置.以下例子只能在本地查询中工作:
1: string[] names = { “James”,“Derek”,“Harry”,“Mary”,“Jack” };
2:
3: IEnumerable<string> query = names
4:
5: .Select ((s,i) => i + “=” + s);
6:
7: foreach(var s in query)
8:
9: Console.WriteLine(s); //0=James, 1=Derek…
子查询与对象层级
你可以通过在select语句中嵌套一个子查询来创建一个对象层级.以下示例返回C:\LINQ下的所有目录, 并且每个元素都拥有一个包含各自目录文件的子集合:
1: DirectoryInfo[] dirs =
2:
3: new DirectoryInfo (@”C:\LINQ”).GetDirectories( );
4:
5: var query =
6:
7: from d in dirs
8:
9: where (d.Attributes & FileAttributes.System) == 0
10:
11: select new
12:
13: {
14:
15: DirectoryName = d.FullName,
16:
17: Created = d.CreationTime,
18:
19: Files =
20:
21: from f in d.GetFiles( )
22:
23: where (f.Attributes & FileAttributes.Hidden) == 0
24:
25: select new { FileName = f.Name, f.Length, }
26:
27: };
此查询里面部分可以被称为相关子查询.当一个子查询引用了外部查询的对象我们可以称它们是相关的-在这个例子中,它引用了d,代表了被枚举的目录.
如果是本地查询, 一个select里面的子查询会引起双延迟执行. 在我们的例子中,目录下的文件不会被选取直到内部foreach表达式被枚举执行.