(一)输入参数
在Lambda表达式中,输入参数是Lambda运算符的左边部分。它包含参数的数量可以为0、1或者多个。只有当输入参数为1时,Lambda表达式左边的一对小括弧才可以省略。输入参数的数量大于或者等于2时,Lambda表达式左边的一对小括弧中的多个参数质检使用逗号(,)分割。
例:
() => Console.WriteLine("Lambda");
a => a * a;
delegate void A(Int32 a, Int32 b);
A a1 = (a,b) => Console.WriteLine(a > b);
//或者A a1= (a,b) => { bool c = a>b; Console.WriteLine(c); }
(二)查询表达式
查询表达式是一种使用查询语法表示的表达式,它用于查询和转换来自任意支持LINQ的数据源中的数据。查询表达式使用许多常见的C#语言构造,易读简洁,容易掌握。它由一组类似于SQL或XQuery的声明性语法编写的子句组成。每一个子句可以包含一个或多个C#表达式。这些C#表达式本身也可能是查询表达式或包含查询表达式。
●查询表达式必须以from子句开头,以select或group子句结束。第一个from子句和最后一个select子句或group子句之间,可以包含一个活多个where子句、let子句、join子 句、orderby子句和group子句,甚至还可以是from子句。它包括8个基本子句,具体说明如下所示。
●from子句:指定查询操作的数据源和范围变量。
●select子句:指定查询结果的类型和表现形式。
●where子句:指定筛选元素的逻辑条件。
●let子句:引入用来临时保存查询表达式中的字表达式结果的范围变量。
●orderby子句:对查询结果进行排序操作,包括升序和降序。
●group子句:对查询结果进行分组。
●into子句:提供一个临时标识符。join子句、group子句或select子句可以通过该标识符引用查询操作中的中坚结果。
●join子句:连接多个用于查询操作的数据源。
int[] arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var query = from n in arr select n;
query.ToList().ForEach(m => {Console.WriteLine(m);});
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query2=from n in arr where n >6 select n;
(三)from
数据源:指定数据的来源,它的形式可以为静态数组、动态数组(Arraylist)、集合、数据集(DataSet)、数据表、MML片段、MML文件等。
如果数据源实现了IEnumerable<T>接口,那么编译器可以推断范围变量的类型为其元素类型。
例如:数据源的类型为IEnumerable<UserInfo>,那么可以推断出范围 变量的类型为UseInfo。
List<UserInfo> list=...
var query =from u in list select u;
下面创建一个查询表达式query。该查询表达式查询list数组中的每一个元素。在query查询表达式中,list数组为数据源,u为范围变量。u范围变量的类型被指定为list数据源的元素类型(UserInfo)。
ArrayList list =new ArrayList();
list.Add(...);
...
var query =from UserInfo u in list
select u;
在查询表达式中,from子句至少有一个。当from子句只有一个时,构成的查询表达式被称为包含单个from子句的查询表达式。一般的,包含单个from子句的查询表达式只包含一个数据源。
在查询表达式中,当from子句有两个或两个以上时,构成的查询表达式被称为包含多个from子句的查询表达式。
int[] arr1= new int[] {0,1,2,3,4,5,6,7,8,9};
int[] arr2=new int[] {0,1,2,3,4,5,6,7,8,9};
var query =from a in arr1
from b in arr2
select a + b;
(四)select
int[] arr =new int[] {0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
select n*10;
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
select new
{
ID=n,
Name =n.ToString()
};
(五)where子句
int[] arr =new int[] {0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
where n <3
select n;
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
where n >3 && n<6
select n;
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
private bool IsEven(int i)
{
return i%2==0?true:false;
}
var query =from n in arr
wehre IsEven(n)
select n;
(六)let子句
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
let isEven =return n%2==0?true:false;
where isEven
select n;
let子句用来创建一个新的范围变量,它用于存储子表达式的结果。let子句使用编程者提供的表达式的结果初始化该变量。一旦初始化了该范围变量的值,它就不能用于存储其他的值。
"return n%2==0?true:false"表达式判断n元素是否为偶数。如果是,则返回true,否则返回false。“let isEven =return n%2==0?true:false”表达式使用let子句创建新的范围变量isEven,用来保存"return n%2==0?true:false"表达式的结果。"where isEven"表达式使用where子句筛选isEven的值为true的元素。
(七)orderby子句
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
where n>1 && n<6
orderby n descending
select n ;
orderby子句可以包含一个或多个排序表达式,各个排序表达式使用逗号(,)分隔。
也可写成 "orderby n%2 ascending,n descending"第一个排序关键字后的"ascending"可以省略。因为默认排序方式为升序。
(八)group子句
group子句用来将查询结果分组,并返回一对象序列。这些对象包含零个或更多个与改组的key值匹配的项,还可以使用group子句结束查询表达式。
注意:每一个分组都不是单个元素,而是一个序列(也属于集合)。
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
where n>1 && n<6
group n by n%2;
query查询表达式的结果是一个序列(类型为IEnumerable<IGrouping<int,int>>),该序列的元素类型为IGrouping<int,int>.其实,该查询结果中的元素也是一个序列。
(九)into子句
into子句可以用来创建一个临时标识符,将group、join或select子句的结果存储到这个标识符中。
int[] arr =new int[]{0,1,2,3,4,5,6,7,8,9};
var query =from n in arr
where n>1&& n<6
group n by n%2 into g
from sn in g
select sn;
上述查询表达式的查询结果包括4个元素,依次为2、4、3和5
(十)join子句
join子句用来连接两个数据源,即设置两个数据源之间的关系。join子句支持以下3种常见联接方式。
内部联接:元素的链接关系 必须同时满足两个数据源,类似于SQL语句中的inner join子句。
分组联接:包含into子句的join子句。
左外部联接:元素的链接关系必须满足联接中的左数据源,类似于SQL语句中的left join子句。
内部联接:join子句的内部联接要求两个数据源都必须存在相同的值,即两个数据源都必须存在满足联接关系的元素。
int[] arra =new int[] {0,1,2,3,4,5,6,7,8,9};
int[] arrb =new int[]{0,2,4,6,8};
var query =from a in arra
where a <7
join b in arrb on a equals b
select a;