文章教程

13.2LINQ基础知识

8/31/2020 9:52:39 PM 人评论 次浏览

13.2 LINQ基础知识

LINQ查询语句能够将复杂的查询应用简化成一个简单的查询语句,不仅如此,LINQ还支持编程语言本有的特性进行高效地数据访问和筛选。使用LINQ查询功能,必须引用System.Linq命名空间。

13.2.1 LINQ查询步骤

虽然LINQ在写法上和SQL语句十分相似,但是LINQ语句在其查询语法上和SQL语句还是有所不同的。如下面的SQL查询语句:

alt

与上面的SQL查询语句相对应的LlNQ查询语句格式如下所示:

alt

上述代码作为LINQ查询语句实现了和SQL查询语句一样的效果,但是LINQ查询语句在格式上与SQL语句不同。LINQ的基本格式如下:

alt

从结构上来看,LINQ查询语句同SQL查询语句中比较大的区别就在于SQL查询语句中的select关键字在语句的前面,而在LINQ查询语句中select关键字在语句的后面,在其他地方没有太大的区别,相信对于熟悉SQL查询语句的人来说非常容易上手。

使用LINQ的查询通常由以下三个不同的操作步骤组成:

(1)获得数据源。

(2)创建查询。

(3)执行查询。

下面通过一个简单的实例来看一下LINQ的查询步骤是如何进行的。

【实例13-1】LINQ查询步骤

本实例通过使用标准的LINQ查询语句获得学生成绩数组中分数大于60分的成绩来演示LINQ查询操作的三个步骤,具体实现步骤如下。

01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例13-1”。

02 在“实例13-1”中创建一个名为Default.aspx的窗体文件。

03 单击网站目录下的Default.aspx.cs文件,编写代码如下:

alt

上面的代码中第1行处理页面Page加载的事件Load。第2行定义了int类型的数组numbers。这个numbers就是LINQ查询操作中的第一步获得数据源。

第10、11行定义隐藏变量numberQuery获得通过关键字from和select创建LINQ查询语句查询numbers数组中的每个int元素。这是LINQ查询操作中的第二步创建查询。

第12行~第14行通过foreach循环语句将查询的结果输出到页面显示,这是LINQ查询操作中的第三步执行查询。

04 按快捷键Ctrl+F5运行程序的效果,运行效果如图13-2所示。

alt

图13-2 运行效果

13.2.2 LINQ和泛型

LINQ查询和泛型有着千丝万缕的关系,从某种意义上来说,泛型是LINQ查询的基础。但是,实际上开发人员并不需要非常熟悉泛型就可以使用LINQ查询。在前文中已经介绍了泛型的概念和使用,这里仅强调两个于LING查询技术密切相关的两个基本概念。

(1)当创建泛型集合类(如List<(Of <(T>)>))的实例时,将T替换为集合中指定的对象类型。例如,字符串集合表示为List<string>,Student对象集合表示为List<Student>。因为泛型集合是强类型的,所以比将元素存储为Object类型的集合要强大的多。如果尝试将Student添加到List<string>,则会在编译时出现一条错误。泛型集合易于使用的原因是不必执行运行时进行强制类型转换。

(2)IEnumerable<(Of<(T>)>)表示是一个接口,通过该接口,可以使用foreach语句来遍历泛型集合类。LINQ查询变量可以类型化为IEnumerable<(Of<(T>)>)或者它的派生类型,如IQueryable<(Of <(T>)>)。当看到类型化为IEnumerable<Book>的查询变量时,这意味着在执行该查询时,该查询将生成包含零个或多个Book对象的集合。例如:

alt

上面的代码中第1行定义一个查询变量bookQuery,该变量的类型为IEnumerable<Book>,第2行~第4行定义了具体的LINQ查询指令,从图书中查询名为三国演义的图书对象。第5行~第8行通过foreach循环遍历显示查询该图书对象的名称和价格。

为了避免使用泛型语法,可以使用匿名类型来声明查询,即使用var关键字来声明查询。var关键字指示编译器通过查看在from子句中指定的数据来推断查询变量的类型,例如:

alt

上述代码除第1行外,这段代码和前面的代码相同。这里查询变量的类型var和Book相同,而Book的类型是IEnumerable<Book>。因此,这段代码和前面的代码具有相同的效果。

13.2.3 LINQ查询表达式

LINQ查询表达式由一组子句组成,这些子句使用类似于SQL的声明性语法编写,每个子句又包含一个或多个C#表达式,而这些表达式本身又可能是查询表达式或包含查询表达式。查询表达式必须以from子句开头,并且必须以select或group子句结尾。在第一个from子句和最后一个select或group子句之间,查询表达式可以包含一个或多个下列可选子句:where、orderby、join、let,甚至可以包括附加的from子句。

1.from子句

查询表达式必须以from子句开头。它同时指定了数据源和范围变量。在对数据源进行遍历的过程中,范围变量表示数据源中的每个元素,并根据数据源中元素类型对范围变量进行强类型化。

2.select子句

使用select子句可以查询所有类型的数据源。简单的select子句只能查询与数据源中所包含的元素具有相同类型的对象。例如代码:

alt

上面的代码中第1行定义查询变量CustomerQuery,第2行定义数据源Customers和范围变量Customer。第3行的orderby子句将根据编号ID重新排序。第4行的select子句查询出已经重新排序后的集合元素。

3.group子句

使用group子句可获得按照指定的键进行分组的元素。键可以采用任何数据类型。例如根据ID属性进行分组查询的代码如下:

alt

上面的代码中第3行根据编号ID对查询结果进行分组。第4行~第9行通过foreach循环遍历查询结果。在使用group子句结束查询时,结果保存在嵌套的集合中,即集合中的每个元素又是另一集合,该子集合中包含根据Key键划分的每个分组对象。在循环访问生成分组对象时,必须使用嵌套的foreach循环。外部循环用于循环访问每个分组对象,内部循环用于循环访问每个组的成员。

4.where子句

where子句通过条件设定对查询的结果进行过滤,从数据源中排除指定的元素。在下面的示例中,只返回名称是“齐飞”的客户:

alt

上面的代码中第3行设置查询的条件:客户名是否叫“齐飞”。通过where子句,排除“齐飞”以外的客户。

如果要使用多个过滤条件的话,需要使用逻辑运算符号,如&&、||等。例如,下面的代码只返回编号是10001且联系电话为021-58862545的客户:

alt

5.order by子句

使用order by子句可以很方便地对返回的数据进行排序。orderby子句对查询返回的元素根据指定的排序类型进行排序。例如,根据ID属性对查询返回的结果进行排序:

alt

上面的代码中第3行使用order by关键字进行排序。Customer类型的ID属性是整形值,执行客户按编号从大到小排序。qscending关键字表示以默认方式按递增的顺序进行排列。Descending关键字则表示把查询出的数据进行逆序排列。

6.联接

在LINQ中,join子句可以将来自不同数据源中没有直接关系的元素进行关联,但是要求两个不同数据源中必须有一个相等元素的值。例如下面对两个数据集arry1和arry2进行连接查询。

alt

上面的代码中第1行创建整形数组arry1作为数据源。第2行创建整形数组arry2作为数据源。第3行表示联接的第一个集合为arry1。第4行表示联接的第二个集合为arry2,当val1%7和val2%9有相同的值时,select子句将val1和val2选择为查询结果。

7.投影

投影操作和SQL查询语句中的SELECT基本类似,投影操作能够指定数据源并选择相应的数据源,能够将集合中的元素投影到新的集合中去,并能够指定元素的类型和表现形式。示例代码如下:

alt

上面的代码中第1行创建整形数组arry作为数据源,第2行使用Select进行同行投影操作将符合条件的元素投影到新的集合lint中去。第3行~第5行循环遍历集合并输出对象。

【实例13-2】LINQ查询表达式的使用

本实例使用LINQ基本的查询操作从新闻集合中查找属于国际新闻的内容并显示在页面,具体实现步骤如下:

01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例13-2”。

02 用右键单击“网站项目名称”,在弹出的快捷菜单中选择“添加”|“添加ASP.NET文件夹”|App_Code命令,此时网站根目录下自动生成一个名为App_Code的文件夹。

03 用右键单击App_Code的文件夹,在弹出的快捷菜单中选择“添加”|“添加新项”命令,弹出“添加新项”对话框。

04 选择“已安装模板”下的“Visual C#”模板,并在模板文件列表中选中“类”选项,然后在“名称”文本框输入该文件的名称News.cs,最后单击“添加”按钮。

05 此时在“App.Code文件夹”下添加了名为News.cs类文件。

06 单击News.cs文件,编写代码如下:

alt

上面的代码中第1行定义了一个News新闻类。第2行~第4行定义了三个属性代表新闻的编号、标题和类别。

07 在“实例13-2”中创建一个名为Default.aspx的窗体文件。

08 单击网站目录下的Default.aspx.cs文件,编写代码如下。

alt

上面的代码中第1行定义处理页面Page加载事件Load的方法。第2行~第9行初始化一个List类型的新闻类集合,其中定义了6个新闻对象。第10行~第12行定义了一个查询表达式,其中,第10行定义了一个查询变量NewsQuery和查询表达式的from子句,m是由News组成的集合,这里被指定为查询的数据源,s是范围变量,因为m是News对象组成的,所以范围变量s也被类型化为News,这样就可以使用点运算符来访问该类型的categories成员。第11行设置查询的排序方式是按照新闻编号大小降序排列。第12行查询返回的结果是符合的新闻类别属于国家新闻的新闻标题名。第14行~第16行通过foreach循环遍历符合要求的变量,并把符合要求的新闻标题显示到网页上。

09 按快捷键Ctrl+F5运行程序的效果如图13-3所示。

alt

图13-3 运行效果

教程类别