第4章 LINQ查询大全
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
·38·
第 4 章 LINQ 查询基础
IQueryable<T>的对象,可以对它进行枚举,遍历每一个元素。此外,它的元素可 以是任何数据类型,所以可以表示任何数据的集合。 目标数据:数据源中的元素并不定是查询所需要的结果。例如,对于一个学生信 息集合中,查询 A 只是查询学生的姓名,查询 B 要查询学生的姓名和各科成绩, 查询 C 则需要学生各科成绩的总分(需要另外计算),而不是原始数据中的各科 成绩。目标数据用来指定查询的具体想要的是什么数据。在 LINQ 中,它定义了 查询结果数据集中元素的具体类型。 筛选条件:筛选条件定义了对数据源中元素的过滤条件。只有满足条件的元素才 作为查询结果返回。筛选条件可以是简单的逻辑表达式表示,也可以用具有复杂 逻辑的函数来表示。 附加操作:附加操作表示一些其他的具体操作。比如,对查询结果进行排序、计 算查询结果的最值和求和、对查询结果进行分组等。 其中,数据源和目标数据是 LINQ 查询的必备元素,筛选条件和附加操作是可选元素。 比如,示例代码 4-1 中的查询 query1 就只包含了数据源和目标数据两个必备元素。本章后 面的章节将进一步介绍 LINQ 查询的具体使用方法。
通常,针对数据的查询是用简单的字符串文本来编写的查询语句,比如传统的 SQL 查 询语句,没有编译时的类型检查,安全性、方便性都不好。此外,开发人员还需要为不同 的数据源学习不同的数据查询语言,比如,查询 SQL 数据库的 T-SQL、查询 XML 数据的 DOM 结构等。
为了解决上面的问题,微软在.NET 3.5 版中推出一项具有突破性的新特性——语言集 成查询(LINQ)。LINQ 是 Language Integrate Query 的缩写,它在对象和数据之间建立一 种对应关系,可以使用访问内存对象的方式查询数据集合。LINQ 使查询成为 C#中的一种 语言构造。开发人员可以在 C#代码中嵌套类似于 SQL 语句的查询表达式,从而实现数据 查询的功能。
LINQ 查询的目的是从指定的数据源中查询满足符合特定条件的数据元素,并且通过 根据需要对这些查询的元素进行排序、连接等操作。所以 LINQ 查询包括如下几个主要 元素。
数据源:数据源表示 LINQ 查询将从哪里查找数据,它通常是一个或多个数据集, 每 个 数 据 集 包 含 一 系 列 的 元 素 。 数 据 集 是 一 个 类 型 为 IEnumerable<T> 或
4.2 LINQ 查询表达式
查询表达式是查询语言最基本的编写格式。同样,LINQ 查询表达式是一种直观、简 洁的查询代码编写方式。本节从多个角度详细介绍 LINQ 查询表达式的格式和具体应用, 包括选择、条件过滤、排序、联接等。
4.2.1 查询表达式
在进行 LINQ 查询的编写之前,首先需要了解查询表达式。查询表达式是 LINQ 查询 的基础,也是最常用的编写 LINQ 查询的方法。查询表达式由查询关键字和对应的操作数 组成的表达式整体。其中,查询关键字是常用的查询运算符。C#为这些运算符提供对应的 关键字,从而更好地与 LINQ 集成。
using System.Linq; using System.Xml.Linq; using System.Data.Linq;
注意:在 Visual Studio 2008 中,通过向导创建项目时,会自动引用 System.Linq 命名空
间,但是其他两个则根据需要手动添加。
·37·
精通 C# 3.0 与.NET 3.5 高级编程——LINQ、WCF、WPF、WF
在 C#中嵌入 LINQ 查询代码非常简单,只需要将 LINQ 查询看成普通的对象代码即可, 如示例代码 4-1 所示。其中,query1 就是一个典型的 LINQ 查询,foreach 语句则是遍历查 询到的结果。从代码中可以看出,可以像使用普通的对象一样使用 LINQ 查询,它并没有 什么特殊之处。
在 4.1.3 节讲到,数据源是 LINQ 查询中必不可少的元素。数据源是实现泛型接口 IEnumerable<T>或 IQueryable<T>的类对象。可以将 IEnumerable<T>简单理解成一个包含 多个元素的列表(或数据库中的表),可以用 foreach 遍历它的所有元素,从而轻松完成查 询操作。由于是泛型接口,所以通过为数据源指定不同的元素类型,可以表示任何数据集 合。在.NET 类库中,列表类、集合类、数组等都实现了接口 IEnumerable<T>,所以可以 直接将这些数据对象作为数据源在 LINQ 查询中使用。
4.1.3 LINQ 查询
LINQ 最具突破性的优势在于将文本查询与对象操作完美集成,它让查询数据和操作 对象一样安全和轻松。查询(Query)是 LINQ 的核心概念之一。
传统意义上的数据查询语言,通常是比较易懂,且有一定语义的文本。例如,在 SQL 查询语法中,用如下所示的 SQL 语句从数据库表 students 中查询所有学生的姓名。传统的 查询语言,通常由查询关键字来定义特定的功能,指定数据源、查询结果、筛选条件等。 例如,下面代码中的 select 和 from 是关键字,分别用来指定要查询的结果和数据源。
根据数据源类型,可以将 LINQ 技术分成如下所述的 4 个主要的技术方向。 LINQ to Object:数据源为实现了接口 IEnumerable<T>或 IQueryable<T>的内存数
据集合,这也是 LINQ 的基础,本章将详细介绍这方面的内容。 LINQ to :数据源为 数据集,这里将数据库中的表结构映射
到类结构,并通过 从数据库中获取到数据集到内存中,通过 LINQ 进行 数据查询。本书第 8 章将详细介绍这一技术。 LINQ to XML:数据源为 XML 文档,这里通过 XElement、XAttribute 等类将 XML 文档数据加载到内存中,通过 LINQ 进行数据查询。本书第 9 章将详细介绍这一 技术。 除了这 3 种常见的数据类型之外,.NET 3.5 还为用户扩展 LINQ 提供了支持,用户可 以根据需要实现第三方的 LINQ 支持程序,然后通过 LINQ 获取自定义的数据源。
IEnumerable<T>接口:它表示可以查询的数据集合,一个查询通常是逐个对集合 中的元素进行筛选操作,返回一个新的 IEnumerable<T>对象,用来保存查询结果。
IQueryable<T>接口:它继承 IEnumerable<T>接口,表示一个可以查询的表达式目 录树。
Enumerable 类:它通过对 IEnumerbale<T>提供扩展方法,实现 LINQ 标准查询运 算符。包括过滤、导航、排序、查询、联接、求和、求最大值、求最小值等操作。
4.1 LINQ 基础概念
LINQ 是微软在.NET Framework 3.5 版中推出的主要新特性之一。它为开发人员提供统 一的数据查询模式,并与.NET 开发语言(如:C#和 )集成,很大程度上简化了数 据查询的编码和调试等,提高数据处理的性能。
4.1.1 什么是 LINQ
如今,软件应用环境越来越多样化,软件需要处理的数据量也日渐庞大,数据之间的 关系日渐复杂。从而带动了存储技术的不断发展,越来越多的数据存储格式被应用到各种 软件场合。
在 C# 3.0 中可以直接使用的查询关键字和功能如表 4.1 所示。通过使用这些查询关键 字,可以编写出功能强大的数据查询程序。
关键字 from select where
orderby
group join
表 4.1 查询表达式关键字 功能
指定要查找的数据源以及范围变量,多个 from 子句则表示从多个数据源中查找数据 指定查询要返回的目标数据,可以指定任何类型,甚至是匿名类型 指定元素的筛选条件,多个 where 子句则表示了并列条件,必须全部都满足才能入选 指定元素的排序字段和排序方式。当有多个排序字段时,由字段顺序确定主次关系,可 指定升序和降序两种排序方式 指定元素的分组字段 指定多个数据源的关联方式
由于 LINQ 中查询表达式访问的是一个对象,所以该对象本身可以表示各种类型的数
第 4 章 LINQ 查询基础
据源。比如 SQL Server 数据库、XML 文档、 数据集,以及内存中的数据集合等。 从而,为不同类型数据源的数据查询提供一种统一的编码方式。在.NET 类库中,LINQ 相 关类库都在 System.Linq 命名空间下。该命名空间提供支持使用 LINQ 进行查询的类和接口, 其中最主要的是两个类和两个接口。
System.Console.Write("{0} ", item); } }
//定义数组 //定义查询语句 //打印输出
最后,就是编译、生成应用程序。
注意:LINQ 是在.NET 3.5 版之后新增的,所以在.NET 2.0 及早期版本程序中直接使用
LINQ 是不能实现的。要在.NET 2.0 及早期版本程序中使用 LINQ,首先需要通过 Visual Studio 2008 将程序自动转化到.NET 3.5 版本。
第 4 章 LINQ 查询基础
随着软件应用领域的不断扩大,软件需要处理的数据类型和数据量与日俱增。数据访 问的通用性、安全性、方便性逐渐引起开发人员和客户的重视。因此,微软公司在.NET3.5 中增加集成语言查询,它为开发人员提供一种统一的数据查询模式,可极大地提高数据访 问的安全性和高效性。通过简洁易用的接口,大大提供了软件开发效率。
·39·
精通 C# PF、WF
本节后面的小节中将进一步对各关键字进行介绍,包括它们的格式、使用方法、技巧 等。查询关键字的实际是在数据源对象及其元素上进行方法调用,将在 4.3 节详细介绍查 询方法的相关知识。
4.2.2 用 from 子句指定数据源
示例代码 4-1 static void Main(string[] args) {
int[] ary = {1, 2, 5, 4, 3, 9, 8, 7 }; var query1 =
from val in ary
select val; foreach (var item in query1) {
LINQ 不是简单地在 C#中嵌套查询表达式,而是将查询表达式作为 C#的一种语法。查 询表达式访问的数据源是包含一组数据的集合对象(IEnumerable<T>或 IQueryable<T>类 型),返回的查询结果也是包含一组数据的集合对象。所以,编译时将对查询的数据类型 进行检查,增强了类型安全性。同时,还可以根据集合类型,在用 Visual Studio 2008 编写 代码使用只能感知功能,使得编码更快捷和轻松。LINQ 还可以通过函数的形式提供过滤 条件等,大大简化了查询表达式的复杂度。
select from students
LINQ 中的查询和传统的查询有一些相似之处,它同样可以采用具有一定语义的文本 来表示,就如示例代码 4-1 中查询 query1 的定义一样,这种方式在 LINQ 中称为查询表达 式。另外,LIIQ 中的查询同时是一个类型为 IEnumerable<T>或 IQueryable<T>的对象,所 以可以通过一种使用对象的方式(使用属性、调用方法等)使用它,这种方式在 LINQ 中 称为查询方法。本章后面的内容将详细介绍如何通过查询表达式和查询方法实现数据查询。
Queryable 类:它通过对 IQueryable<T>提供扩展方法,实现 LINQ 标准查询运算符。 包括过滤、导航、排序、查询、联接、求和、求最大值、求最小值等操作。
注意:深入学习 LINQ 之前,读者应该具备 LINQ 所用到 C#高级语言特性,包括接口、
泛型、扩展方法、可变类型、匿名类型等。
4.1.2 如何使用 LINQ
LINQ 作为一种数据查询编码方式,它本身并不是独立的开发语言,也不能进行应用 程序开发。但是在.NET 3.5 中,可以在 C#中集成 LINQ 查询代码。
在任何源代码文件中,要使用 LINQ 查询功能,必须引用 System.Linq 命名空间。使用 LINQ to XML 要引用 System.Xml.Linq 命名空间,使用 LINQ to 要引用 System.Data.Linq 命名空间。代码如下所示。
第 4 章 LINQ 查询基础
IQueryable<T>的对象,可以对它进行枚举,遍历每一个元素。此外,它的元素可 以是任何数据类型,所以可以表示任何数据的集合。 目标数据:数据源中的元素并不定是查询所需要的结果。例如,对于一个学生信 息集合中,查询 A 只是查询学生的姓名,查询 B 要查询学生的姓名和各科成绩, 查询 C 则需要学生各科成绩的总分(需要另外计算),而不是原始数据中的各科 成绩。目标数据用来指定查询的具体想要的是什么数据。在 LINQ 中,它定义了 查询结果数据集中元素的具体类型。 筛选条件:筛选条件定义了对数据源中元素的过滤条件。只有满足条件的元素才 作为查询结果返回。筛选条件可以是简单的逻辑表达式表示,也可以用具有复杂 逻辑的函数来表示。 附加操作:附加操作表示一些其他的具体操作。比如,对查询结果进行排序、计 算查询结果的最值和求和、对查询结果进行分组等。 其中,数据源和目标数据是 LINQ 查询的必备元素,筛选条件和附加操作是可选元素。 比如,示例代码 4-1 中的查询 query1 就只包含了数据源和目标数据两个必备元素。本章后 面的章节将进一步介绍 LINQ 查询的具体使用方法。
通常,针对数据的查询是用简单的字符串文本来编写的查询语句,比如传统的 SQL 查 询语句,没有编译时的类型检查,安全性、方便性都不好。此外,开发人员还需要为不同 的数据源学习不同的数据查询语言,比如,查询 SQL 数据库的 T-SQL、查询 XML 数据的 DOM 结构等。
为了解决上面的问题,微软在.NET 3.5 版中推出一项具有突破性的新特性——语言集 成查询(LINQ)。LINQ 是 Language Integrate Query 的缩写,它在对象和数据之间建立一 种对应关系,可以使用访问内存对象的方式查询数据集合。LINQ 使查询成为 C#中的一种 语言构造。开发人员可以在 C#代码中嵌套类似于 SQL 语句的查询表达式,从而实现数据 查询的功能。
LINQ 查询的目的是从指定的数据源中查询满足符合特定条件的数据元素,并且通过 根据需要对这些查询的元素进行排序、连接等操作。所以 LINQ 查询包括如下几个主要 元素。
数据源:数据源表示 LINQ 查询将从哪里查找数据,它通常是一个或多个数据集, 每 个 数 据 集 包 含 一 系 列 的 元 素 。 数 据 集 是 一 个 类 型 为 IEnumerable<T> 或
4.2 LINQ 查询表达式
查询表达式是查询语言最基本的编写格式。同样,LINQ 查询表达式是一种直观、简 洁的查询代码编写方式。本节从多个角度详细介绍 LINQ 查询表达式的格式和具体应用, 包括选择、条件过滤、排序、联接等。
4.2.1 查询表达式
在进行 LINQ 查询的编写之前,首先需要了解查询表达式。查询表达式是 LINQ 查询 的基础,也是最常用的编写 LINQ 查询的方法。查询表达式由查询关键字和对应的操作数 组成的表达式整体。其中,查询关键字是常用的查询运算符。C#为这些运算符提供对应的 关键字,从而更好地与 LINQ 集成。
using System.Linq; using System.Xml.Linq; using System.Data.Linq;
注意:在 Visual Studio 2008 中,通过向导创建项目时,会自动引用 System.Linq 命名空
间,但是其他两个则根据需要手动添加。
·37·
精通 C# 3.0 与.NET 3.5 高级编程——LINQ、WCF、WPF、WF
在 C#中嵌入 LINQ 查询代码非常简单,只需要将 LINQ 查询看成普通的对象代码即可, 如示例代码 4-1 所示。其中,query1 就是一个典型的 LINQ 查询,foreach 语句则是遍历查 询到的结果。从代码中可以看出,可以像使用普通的对象一样使用 LINQ 查询,它并没有 什么特殊之处。
在 4.1.3 节讲到,数据源是 LINQ 查询中必不可少的元素。数据源是实现泛型接口 IEnumerable<T>或 IQueryable<T>的类对象。可以将 IEnumerable<T>简单理解成一个包含 多个元素的列表(或数据库中的表),可以用 foreach 遍历它的所有元素,从而轻松完成查 询操作。由于是泛型接口,所以通过为数据源指定不同的元素类型,可以表示任何数据集 合。在.NET 类库中,列表类、集合类、数组等都实现了接口 IEnumerable<T>,所以可以 直接将这些数据对象作为数据源在 LINQ 查询中使用。
4.1.3 LINQ 查询
LINQ 最具突破性的优势在于将文本查询与对象操作完美集成,它让查询数据和操作 对象一样安全和轻松。查询(Query)是 LINQ 的核心概念之一。
传统意义上的数据查询语言,通常是比较易懂,且有一定语义的文本。例如,在 SQL 查询语法中,用如下所示的 SQL 语句从数据库表 students 中查询所有学生的姓名。传统的 查询语言,通常由查询关键字来定义特定的功能,指定数据源、查询结果、筛选条件等。 例如,下面代码中的 select 和 from 是关键字,分别用来指定要查询的结果和数据源。
根据数据源类型,可以将 LINQ 技术分成如下所述的 4 个主要的技术方向。 LINQ to Object:数据源为实现了接口 IEnumerable<T>或 IQueryable<T>的内存数
据集合,这也是 LINQ 的基础,本章将详细介绍这方面的内容。 LINQ to :数据源为 数据集,这里将数据库中的表结构映射
到类结构,并通过 从数据库中获取到数据集到内存中,通过 LINQ 进行 数据查询。本书第 8 章将详细介绍这一技术。 LINQ to XML:数据源为 XML 文档,这里通过 XElement、XAttribute 等类将 XML 文档数据加载到内存中,通过 LINQ 进行数据查询。本书第 9 章将详细介绍这一 技术。 除了这 3 种常见的数据类型之外,.NET 3.5 还为用户扩展 LINQ 提供了支持,用户可 以根据需要实现第三方的 LINQ 支持程序,然后通过 LINQ 获取自定义的数据源。
IEnumerable<T>接口:它表示可以查询的数据集合,一个查询通常是逐个对集合 中的元素进行筛选操作,返回一个新的 IEnumerable<T>对象,用来保存查询结果。
IQueryable<T>接口:它继承 IEnumerable<T>接口,表示一个可以查询的表达式目 录树。
Enumerable 类:它通过对 IEnumerbale<T>提供扩展方法,实现 LINQ 标准查询运 算符。包括过滤、导航、排序、查询、联接、求和、求最大值、求最小值等操作。
4.1 LINQ 基础概念
LINQ 是微软在.NET Framework 3.5 版中推出的主要新特性之一。它为开发人员提供统 一的数据查询模式,并与.NET 开发语言(如:C#和 )集成,很大程度上简化了数 据查询的编码和调试等,提高数据处理的性能。
4.1.1 什么是 LINQ
如今,软件应用环境越来越多样化,软件需要处理的数据量也日渐庞大,数据之间的 关系日渐复杂。从而带动了存储技术的不断发展,越来越多的数据存储格式被应用到各种 软件场合。
在 C# 3.0 中可以直接使用的查询关键字和功能如表 4.1 所示。通过使用这些查询关键 字,可以编写出功能强大的数据查询程序。
关键字 from select where
orderby
group join
表 4.1 查询表达式关键字 功能
指定要查找的数据源以及范围变量,多个 from 子句则表示从多个数据源中查找数据 指定查询要返回的目标数据,可以指定任何类型,甚至是匿名类型 指定元素的筛选条件,多个 where 子句则表示了并列条件,必须全部都满足才能入选 指定元素的排序字段和排序方式。当有多个排序字段时,由字段顺序确定主次关系,可 指定升序和降序两种排序方式 指定元素的分组字段 指定多个数据源的关联方式
由于 LINQ 中查询表达式访问的是一个对象,所以该对象本身可以表示各种类型的数
第 4 章 LINQ 查询基础
据源。比如 SQL Server 数据库、XML 文档、 数据集,以及内存中的数据集合等。 从而,为不同类型数据源的数据查询提供一种统一的编码方式。在.NET 类库中,LINQ 相 关类库都在 System.Linq 命名空间下。该命名空间提供支持使用 LINQ 进行查询的类和接口, 其中最主要的是两个类和两个接口。
System.Console.Write("{0} ", item); } }
//定义数组 //定义查询语句 //打印输出
最后,就是编译、生成应用程序。
注意:LINQ 是在.NET 3.5 版之后新增的,所以在.NET 2.0 及早期版本程序中直接使用
LINQ 是不能实现的。要在.NET 2.0 及早期版本程序中使用 LINQ,首先需要通过 Visual Studio 2008 将程序自动转化到.NET 3.5 版本。
第 4 章 LINQ 查询基础
随着软件应用领域的不断扩大,软件需要处理的数据类型和数据量与日俱增。数据访 问的通用性、安全性、方便性逐渐引起开发人员和客户的重视。因此,微软公司在.NET3.5 中增加集成语言查询,它为开发人员提供一种统一的数据查询模式,可极大地提高数据访 问的安全性和高效性。通过简洁易用的接口,大大提供了软件开发效率。
·39·
精通 C# PF、WF
本节后面的小节中将进一步对各关键字进行介绍,包括它们的格式、使用方法、技巧 等。查询关键字的实际是在数据源对象及其元素上进行方法调用,将在 4.3 节详细介绍查 询方法的相关知识。
4.2.2 用 from 子句指定数据源
示例代码 4-1 static void Main(string[] args) {
int[] ary = {1, 2, 5, 4, 3, 9, 8, 7 }; var query1 =
from val in ary
select val; foreach (var item in query1) {
LINQ 不是简单地在 C#中嵌套查询表达式,而是将查询表达式作为 C#的一种语法。查 询表达式访问的数据源是包含一组数据的集合对象(IEnumerable<T>或 IQueryable<T>类 型),返回的查询结果也是包含一组数据的集合对象。所以,编译时将对查询的数据类型 进行检查,增强了类型安全性。同时,还可以根据集合类型,在用 Visual Studio 2008 编写 代码使用只能感知功能,使得编码更快捷和轻松。LINQ 还可以通过函数的形式提供过滤 条件等,大大简化了查询表达式的复杂度。
select from students
LINQ 中的查询和传统的查询有一些相似之处,它同样可以采用具有一定语义的文本 来表示,就如示例代码 4-1 中查询 query1 的定义一样,这种方式在 LINQ 中称为查询表达 式。另外,LIIQ 中的查询同时是一个类型为 IEnumerable<T>或 IQueryable<T>的对象,所 以可以通过一种使用对象的方式(使用属性、调用方法等)使用它,这种方式在 LINQ 中 称为查询方法。本章后面的内容将详细介绍如何通过查询表达式和查询方法实现数据查询。
Queryable 类:它通过对 IQueryable<T>提供扩展方法,实现 LINQ 标准查询运算符。 包括过滤、导航、排序、查询、联接、求和、求最大值、求最小值等操作。
注意:深入学习 LINQ 之前,读者应该具备 LINQ 所用到 C#高级语言特性,包括接口、
泛型、扩展方法、可变类型、匿名类型等。
4.1.2 如何使用 LINQ
LINQ 作为一种数据查询编码方式,它本身并不是独立的开发语言,也不能进行应用 程序开发。但是在.NET 3.5 中,可以在 C#中集成 LINQ 查询代码。
在任何源代码文件中,要使用 LINQ 查询功能,必须引用 System.Linq 命名空间。使用 LINQ to XML 要引用 System.Xml.Linq 命名空间,使用 LINQ to 要引用 System.Data.Linq 命名空间。代码如下所示。