要使用LINQ来编程,首先要学会使用由LINQ的子句和关键字以及按查询语法组成的查询表达式。这里要说明,.NET公共语言运行库(CLR)本身并不具有查询语法的概念,在编译时,查询表达式会自动转换为CLR确实了解的内容(方法调用)。
LINQ表达式的作用就是从给定一个或多个数据源中,按照指定的条件检索数据,检索出的结果按找指定类型或表现形式返回。
数据源可以是数据库对象或XML流等,也可以是实现了IEnumerable或者泛型IEnumerable<T>接口的集合对象,这些都可以被当作LINQ的数据源来使用
LINQ基本语法包含如下8个上下文关键字,具体说明如下:
- from:指定数据源和范围变量
- where:根据布尔表达式(由逻辑“与”、逻辑“或”等组成)从数据园中筛选 元素
- select指定查询结果中的元素所具有的类型或表现形式
- group:对指定查询结果按键值进行分组
- into:提供一个标识符,它可以充当对jion/group或select子句结果的引用
- orderby:对查询出的元素进行排序
- join:按照两个指定匹配条件来联接两个数据源
- let:产生一个用于存储查询表达式中的子表达式查询结果的范围变量
下面的一个实例演示LINQ表达式的简单应用:
Linq表达式是以from子句开头,LINQ表达式的结束则必须是select子句或group子句。
1.from子句
1)对于from子句中的范围变量,如果没有指定数据类型,并且数据源类型实现了IEnumerable<T>接口,那么编译器会 根据数据源的数据类型自动推断出其数据类型,数据源仅仅实现了IEnumerable接口(例如ArrayList类型),则必须指定from子句中范围变量的数据类型,下面的控制台应用程序DemoLinq2演示了用LINQ查询ArrayList
项目中添加GuestInfo.cs类:
在Program.cs文件中输入下面的代码 :
LINQ表达式 的数据源可以是List<T>、int[]、ArrayList、 string[]等各种实现了IEnumerable或泛型IEnumberable<T>接口的对象集合,另外,由于string对象其实也是一个字符数组,所以单个字符串对象也可作为LINQ表达式的数据源。
2)复合from子句
在查询数据源 中,元素的集合类型属性中的元素,可以使用复合from子句完成,例如,在信息社会中,一个客户有多个联系电话是很普遍的现象,可和信息类型GuextInfo中包含一个电话表的集合属性(TelTable),如果想查询电话属于那个客户,就需要使用符合from子句
下面的实例演示了用复合from子句查询客户多个电话号码中的号码
添加现有项,既“GuestInfo.cs”文件,然后在Program.cs中输入下面的代码:
3)多个from子句
多个from子句查询和 复合from子句查询从字面上看似乎一样,其实是不同的操作,复合from子句查询是查询单个数据源中的子元素的集合,而多个from子句查询,是载入多个数据源进行查询。
下面的控制台应用 程序DemoFrom2演示了 用多个from子句完全交叉联接的电话表
添加现有项“GuestInfo.cs”的文件,在Program.cs文件中输入下面的代码:
3.where子句
where子句是LINQ表达式的元素筛选机制,除了开始和结束位置,它集合可以用在LINQ表达式中的任意位置上。
在一个LINQ表达式中,可以有where子句,也可以没有;可以有1个,也可以有多个;多个where子句之间的逻辑关系相当于逻辑关系中的逻辑“与“,每个where子句可以包含1个或多个布尔逻辑 表达式,这些条件称作”谓词“,多个谓词之间用布尔运算符分割,例如逻辑”与“、逻辑”或“等,这些布尔运算副使用c#语言构造
1)常见的where子句查询
下面的控制台应用程序DemoWhere1演示了where子句中多个谓词的LINQ查询实例:
添加现有项:GuestInfo.cs
在Program.cs文件中输入下面的代码:
2)where子句使用自定义函数
添加 现有项:GuestInfo.cs
在Promgram.cs文件中输入下面的代码:
3)动态谓词的筛选
上面的例子都是想定了查询谓词然后进行查询,而有些谓词的数量可能并不固定,是随着情况而变化的,例如,有一组名字,可能 是运行时刻建立的,想查询一下客户信息表中是否有包含这组名字中的记录。
如下面的控制台应用程序DemoWhere3演示:
添加 现有项:GuestInfo.cs
在Program.cs文件中输入下面的代码:
Contains方法几乎存在于所有的.NET集合或这数组类型中,所以,如果想实现动态谓词的筛选只要建立一个实现了Contains的集合或数组,然后把需要查询的谓词添加进去,在LINQ表达式的where子句中使用即可。
4.select子句
LINQ表达式中的查询结果,是使用select子句获得的。select子句还可以进行数据转换 工作,这个 过程称作”投影“,select子句产生的内容,取决于前面所有子句和其自身的表达式执行结果。下面的控制台应用程序DemoSelect1对查询结果进行投影;
添加现有项:GuestInfo.cs
添加新类:MyGuestInfo.cs
在Program.cs文件下 输入下面的代码:
5.group子句
按照语法规定,LINQ表达式必须以from子句开头,以select或group子句结束,所以除了使用select来返回结果外,也可以使用group子句来返回元素元素分组后的结果。
group子句返回的是一个基于IGouping<Tkey,TElement>泛型接口的对象序列。
分组查询是关系型数据库中非常常见的一种操作,但在没有使用LINQ以前,对内存对象进行分组查询是比较麻烦的一件事,现在,在LINQ表达式中只需要使用group子句就可以轻松完成对内存对象的分组。
下面的控制台应用程序DemoGroup演示了分组查询:
添加现有项:GuestInfo.cs
在Program.cs文件中输入如下代码:
键值根据需要,可以使用具有任何类型的任何变量,并且可以对范围变量 进行处理或干脆直接是几乎如一个键值,例如:
group guest by MyProc(guest)或者group guest by "分组键"
6.into子句
into子句 作为一个临时标识符,用于group、select、join子句中。
控制台应用程序DemoInto:
项目中添加现有项:GuestInfo.cs
Program.cs类中代码如下:
into子句提供了一个临时标识符,它存储了into子句前面的查询内容,使它后面的子句可以方便地使用,对齐进行再次查询或排序、投影等操作。
7.排序子句
1) OrderBy和OrderByDescending
控制台应用程序DemoSort1:
添加现有项:GuestInfo.cs
在Program.cs文件中输入下面的代码:
2)ThenBy和ThenByDescending
ThenBy、ThenByDescending用于对元素进行次要排序。
ThenBy用于按照元素的值进行次要的升序排序,语法:
orderby 用于排序的元素表达式 , 用于排序的元素表达式
ThenByDescending用于按照元素的值进行次要降序排序,语法:
orderby 用于排序的元素表达式,用于排序的元素表达式 descending
控制台应用程序DemoSort2:
添加现有项:GuestInfo.cs
Program.cs:
LINQ的排序子句中还有ascending关键字,它是升序关键字,默认可以省略。orderby关键字后面可以有多个排序条件,每个条件用逗号分隔,ascending升序关键字、descending降序关键字可以跟任何条件匹配一次或多次。
8 let子句
let语句用于 在LINQ表达式中存储子表达式的计算结果。let子句创建一个范围变量来 存储结果,变量被创建后,不能修改或办其他表达式的结果重新赋值给它,此范围变量可以在后继的LINQ子句中 使用。
控制台应用程序:DemoLet
添加现有项:GuestInfo.cs
Program.cs:
上例使用let子句建立一个范围变量,这个范围变量在后继的where子句中使用。
9.join子句
如果一个数据源中的元素的某个属性可以跟另外一个数据源 中的元素的属性进行相等比较,那么这两个数据源可以用join子句进行关联。
join子句使用equals关键字进行相等比较,而不是常用的双等号。
DemoJoin控制台应用程序:
添加现有项:GuestInfo.cs
添加名称为GuestTitle的类:
Program.cs: