查询主体中的from…let…where片段
可选的from…let…where部分是查询主体的第一部分,可以由任意数量的3个子句来组合–from子句、let子句和where子句。
from子句
查询表达式从必需的from子句开始,后面跟查询主体。主体本身可以从任何数量的其他from子句开始,每个from子句都指定了一个额外的源数据集合并引入了要在之后运算的迭代变量,所有from子句的语法和含义都一样。
例:from子句示例
class Program { static void Main() { var groupA=new[]{3,4,5,6}; var groupA=new[]{6,7,8,9}; var someInts=from a in groupA from b in groupB where a>4&&b<=8 select new{a,b,sum=a+b};//匿名类型对象 foreach(var a in someInts) { Console.WriteLine(a); } } }
let子句
let子句接受一个表达式的运算并且把它赋值给一个需要在其他运算中使用的标识符。let子句的语法如下:
let Identifier=Expression
例:let子句示例
class Program { static void Main() { var groupA=new[]{3,4,5,6}; var groupA=new[]{6,7,8,9}; var someInts=from a in groupA from b in groupB let sum=a+b //在新的变量中保存结果 where sum==12 select new{a,b,sum}; foreach(var a in someInts) { Console.WriteLine(a); } } }
where子句
where子句根据之后的运算来筛选指定项。
只要是在from…let…where部分中,查询表达式可以有多个where。
例:where子句示例
class Program { static void Main() { var groupA=new[]{3,4,5,6}; var groupA=new[]{6,7,8,9}; var someInts=from a in groupA from b in groupB let sum=a+b where sum>=11 ←条件1 where a==4 ←条件2 select new{a,b,sum}; foreach(var a in someInts) { Console.WriteLine(a); } } }
orderby子句
orderby子句根据表达式按顺序返回结果项。
orderby子句语法如下图。可选的ascending和descending关键字设置了排序方向。表达式通常是项的一个字段。该字段不一定非得是数值字段,也可以是字符串这样的可排序类型。
例:按照学生年龄排序
class Program { static void Main() { var students=new[] { new{LName="Jones",FName="Mary",Age=19,Major="History"}, new{LName="Smith",FName="Bob",Age=20,Major="CompSci"}, new{LName="Fleming",FName="Carol",Age=21,Major="History"}, }; var query=from student in students orderby student.Age select student; foreach(var s in query) { Console.WriteLine("{0},{1}: {2} - {3}",s.LName,s.FName,s.Age,s.Major); } } }
group子句
group子句把select的对象根据一些标准进行分组。例如,之前示例的学士数组,程序可以根据它们的主修课程进行分组。
- 如果项包含在查询的结果中,它们就可以根据某个字段的值进行分组。作为分组依据的属性叫做键(key)
- group子句返回的不是原始数据源中项的枚举,而是返回可以枚举已经形成的项的分组的可枚举类型
- 分组本身是可枚举类型,它们可以枚举实际的项
例:根据学士的主修课程进行分组
using System; using System.Linq; class Program { static void Main() { var students=new[] { new{LName="Jones",FName="Mary",Age=19,Major="History"}, new{LName="Smith",FName="Bob",Age=20,Major="CompSci"}, new{LName="Fleming",FName="Carol",Age=21,Major="History"}, }; var query=from s in students group s by s.Major; foreach(var s in query) { Console.WriteLine("{0}",s.Key); foreach(var t in s) { Console.WriteLine(" {0},{1}",t.LName,t.FName); } } } }
查询延续:into子句
查询延续子句可以接受查询的一部分结果并赋予一个名字,从而可以在查询的另一部分中使用。
例:连接groupA和groupB并命名为groupAandB
class Program { static void Main() { var groupA=new[]{3,4,5,6}; var groupA=new[]{6,7,8,9}; var someInts=from a in groupA join b in groupB on a equals b into groupAandB from c in groupAandB select c; foreach(var a in someInts) { Console.WriteLine(a); } } }
标准查询运算符
标准查询运算符由一系列API方法组成,它能让我们查询任何.NET数组或集合。
标准查询运算符的重要特性如下:
- 被查询的集合对象叫做序列,它必须实现
IEnumerable<T>
接口,T是类型 - 标准查询运算符使用方法语法
- 一些运算符返回IEnumerable对象(或其他序列),而其他的一些运算符返回标量。返回标量的运算符立即执行,并返回一个值
- 很多操作都以一个谓词作为参数。谓词是一个方法,它以对象为参数,根据对象是否满足某条件而返回true或false
例:Sum和Count运算符的使用
class Program { static int[] numbers=new int[]{2,4,6}; static void Main() { int total=numbers.Sum(); int howMany=number.Count(); Console.WriteLine("Total: {0},Count: {1}",total,howMany); } }