2022年完整word版,ASP.NET开发大全第章.ASP.NET.与LINQ.docx
精选学习资料 - - - - - - - - - 第 20 章 ASP.NET 3.5 与 LINQ 对于长期进展的面对对象编程模型而言,其进展基本处于一个比较稳固的阶段,可是面对对象的编程模型并没有解决数据的拜访和整合的复杂问题;对于数据库的拜访和XML的拜访,面对对象方法论无法从根本意义上解决其复杂度和难度,而LINQ 供应了一种更好的解决方案;20.1 什么是 LINQ 任何技术都不行能凭空搭建起来,为明白决工业生产生中某个实际问题,当现有的技术已经无法很好的完成工业的要求,就会促发新技术的产生;LINQ就是为明白决复杂的数据拜访和整合而显现的一种新技术;20.1.1 LINQ 起源从传统的意义上来说,面对过程的编程模型在数据拜访和整合的才能上有肯定的限度;由于面对过 程的编程方法不能很好的描述一个事务,必需通过不同函数之间的调用来描述一个现有的对象,而且面 向过程的编程方法在代码复用性上比较低,所以当面对过程的编程语言需要对数据库进行拜访时,就需 要编写大量的额外代码;虽然面对过程的编程模型可以通过良好的函数引用和编码提高复用性,但是并 没有解决面对过程编程模型中对数据的拜访和整合的复杂度;随着运算机和编程模型的进展,人们发觉了另一个更好的编程模型,这就是现在最常用的面对对象 编程模型;相比面对过程的编程模型而言,面对对象的编程模型能够更好的描述一个事务,事务能够通 过面对对象中的属性、字段和方法很好的模拟实际的事务,而面对对象编程模型中的派生、继承等特性 同样能够极大的提高代码的复用性,提升开发效率;但是面对对象的编程模型同样没有解决复杂的数据库拜访和数据整合,开发人员仍是需要通过繁琐的手段进行数据库的拜访和数据整合;在.NET 3.0 框架或更早, LINQ 就已经被提及, LINQ 是一种能够快速对大部分数据源进行拜访和数据整合的一种技术,对和解决的问题;虽然面对对象的数据库已经在几年前就被提及并且各大 但是传统的关系型数据库在当今仍是应用最为广泛的;LINQ 解决了复杂的数据应用中开发人员需要面 IT 公司投入了对面对对象的数据库的研发,关系型数据库中将数据整合和出现成为一张张的表的形式, 开发人员和数据库治理人员能够通过SQL 治理工具供应的SQL 语句进行数据的查询和整理;但是在开发过程中,开发人员不能够像使用SQL 语句一样对数据集进行查询和处理;任何数据库中的数据都会以一种数据集的形式反馈给用户,这种数据集的形式可以反映成为数学中的集合的概念,其实 在数据库早期的进展中,数据是以集合的概念出现的,而随着数据库的进展,集合的概念照旧是数据库 最基本的概念;正式由于如此,开发人员不能够便利的是从一个集合中查询数据,这里不仅仅是一个数据库,仍包括其他能够以数据库形式存在的文件,例如 ACCESS 、TXT 等,当在开发中需要使用到多个数据库或者数据描述形式的文件时,更多的情形是将这些数据填充到数据集中并通过遍历来拜访数据,这样却造成名师归纳总结 - - - - - - -第 1 页,共 18 页精选学习资料 - - - - - - - - - 了更多的数据拜访问题和麻烦;LINQ 能够很便利的进行数据的查询,使用LINQ 对数据集进行查询的形式很像使用SQL 语句对数据库中的表进行查询,而与之不同的是,LINQ 能够面对更多的对象,这些对象包括数组、集合以及数据库, LINQ 对数组的查询示例代码如下所示;static void Mainstring args string str = " 你好 ","今日的 ","天气真不错 ","生活很阳光 " /创建数组var s = from n in str select n; /编写查询字串foreach var n in s /遍历查询对象 Console.WriteLinen.ToString; /输出对象值 Console.ReadKey; /等待用户按键 上述代码对数组 str 进行了查询, 这种方式很像 SQL 语句;的确 LINQ 的查询方式和 SQL 语句很像,其语法和基本内容都没有什么太大的差别,但是 LINQ 供应了更好的查询的解决方案;LINQ 能够查询更多对象(例如上述代码中的数组)而无法使用 SQL 语句进行查询;另外,LINQ 查询语句仍能够使用WHERE 等关键字进行查询,示例代码如下所示;static void Mainstring args string str = " 你好 ","今日的 ","天气真不错 ","生活很阳光 " /创建数组var s = from n in str where n.Length > 3 select n; /使用条件查询foreach var n in s /遍历查询对象 Console.WriteLinen.ToString; /输出对象值 Console.ReadKey; /等待用户按键 上述代码修改了 LINQ 查询语句,为 LINQ 查询语句增加了条件查询,该条件的意义为查询字符串长度大于 3 的字符串,运行后如图 20-1 所示;图 20-1 LINQ 查询语句从上图可以看出,能够使用类似于SQL 语句的形式进行数据集的查询,很大程度上便利了开发人员对于数据库中数据的拜访和整理;LINQ 可以使用条件语句进行挑选,并且能够使用 .NET 供应的语法进行判定,这样就简化了开发人员对于数据集中的数据的挑选;有关 具体的讲解;LINQ 的语句,会在后面的章节中492 名师归纳总结 - - - - - - -第 2 页,共 18 页精选学习资料 - - - - - - - - - 20.1.2 LINQ 构架在.NET 3.5 中, LINQ ( Language Integrated Query)已经成为了编程语言的一部分,开发人员已经能够使用 Visual Studio 2022 创建使用 LINQ 的应用程序; LINQ 对基于 .NET 平台的编程语言供应了标准的查询操作;在 .NET 3.5 中, LINQ 的基本构架如图 20-2 所示;图 20-2 LINQ 基本构架如图 20-2 所示, LINQ 能够对不同的对象进行查询;在.NET 3.5 中,微软供应了不同的命名空间以支持不同的数据库协作 LINQ 进行数据查询; 在 LINQ 框架中,处于最上方的就是 LINQ 应用程序,LINQ应用程序基于 .NET 框架而存在的, LINQ 能够支持 C#、VB 等.NET 平台下的宿主语言进行 LINQ 查询;在 LINQ 框架中, 仍包括 Linq Enabled ADO.NET 层,该层供应了 LINQ 查询操作并能够供应数据拜访和整合功能;LINQ 包括五个部分, 这五个部分分别是LINQ to Objects 、LINQ to DataSet 、LINQ to SQL 、LINQ to Entities 、LINQ to XML,在.NET 开发中最常用的是LINQ to SQL和 LINQ to XML,本书也具体介绍LINQ的这两个部分;LINQ to SQL 供应了对 SQL Server 中数据库的拜访和整合功能,同时能够以对象的形式进行数据库治理,前面已经提到,现在的数据库照旧以关系型数据库为主,在面对对象开发过程中,很难通过对象的方法描述数据库,而 LINQ 供应了通过对象的形式对数据库进行描述;LINQ to XML 供应了对 XML中数据集的拜访和整合功能,LINQ to XML 使用 System.Xml.Linq 命名控件,为 XML 操作供应了高效易用的方法;20.1.3 LINQ 与 Visual Studio 2022 新特性讲到 LINQ 就不得不讲解 Visual Studio 2022 的新特性, LINQ 作为 Visual Studio 2022 中的一部分,Visual Studio 2022 为 LINQ 供应很好的编程环境,LINQ 也使用到了 C#编程语言中的许多特性,以提高493 名师归纳总结 - - - - - - -第 3 页,共 18 页精选学习资料 - - - - - - - - - 开发人员的开发效率;Visual Studio 2022 重定向:使用 Visual Studio 2022 与 Visual Studio 2005 不同的是, Visual Studio 2022 支持多个版本 .NET 框架的共存, 在 Visual Studio 2022 中可以挑选基于 .NET 2.0 或.NET 3.X版本的框架来开发不同的应用程序,当挑选不同的应用程序基础框架时,Visual Studio 2022 能够智能的供应不同的命名空间;Visual Studio 2022 AJAX :在 ASP.NET 2.0 开发中, 需要使用 ASP.NET AJAX 1.0 作为 AJAX 开发必备的工具,在 Visual Studio 2022 中已经集成了对 AJAX 的支持,创建 ASP.NET 3.5 应用程序已经能够特别便利的使用 AJAX 功能;Visual Studio 2022 可视化操作: 在 Visual Studio 2022 中,微软供应了可视化操作,开发人员能够挑选不同的视图进行页面分别形式的开发,在 拆分,代码三种视图进行不同的开发体验;Visual Studio 2022 中开发人员可以挑选视图,Visual Studio 2022 集成 LINQ :这是 Visual Studio 2022 中比较值得期望的功能,Visual Studio 2022将 LINQ 作为编程语言中的一部分,为开发人员供应了LINQ 开发的原生环境;在 LINQ 与 Visual Studio 2022 中,开发人员最为期望的新特性仍是 Visual Studio 2022 对 LINQ 的原生支持, 使用 LINQ 能够快速的进行数据库的拜访和整合,这样在肯定的意义上降低了开发难度,LINQ在.NET Framework 3.5 中的位置如图 20-3 所示;图 20-3 .NET 框架中的 LINQ 正如图 20-3 所示, .NET 2.0 后面几个版本的框架都是基于.NET Framework 2.0 而存在的,在 .NET Framework 3.0 中,微软已经增加了 WPF,WCF, WF 等新特性以供应快速的面对服务的开发和完善的用户体验解决方案;而 LINQ 是作为 .NET Framework 3.5 存在于 .NET Framework 中的,这也就是说只有在.NET Framework 3.5 框架中才能够使用 LINQ 技术;由于 .NET Framework 3.5 版本的框架基于 .NET Framework 3.0 版本,开发人员可以使用 LINQ 特性进行分布式开发和面对服务的开发,这样就能够更近一步的提高代码的复用性和安全性;20.2 LINQ 与 Web 应用程序在 ASP.NET 应用程序开发中,经常需要涉及到数据的显式和整合,使用 ASP.NET 2.0 中供应的控件能够编写用户控件,开发人员仍能够挑选开发自定义控件进行数据显示和整合,但是在数据显示和整494 名师归纳总结 - - - - - - -第 4 页,共 18 页精选学习资料 - - - - - - - - - 合过程中, 开发人员往往需要大量的连接、关闭连接等操作, 而且传统的方法也破坏了面对对象的特性,使用 LINQ 能够便利的使用面对对象的方法进行数据库操作;20.2.1 创建使用 LINQ 的 Web 应用程序创建 LINQ 的 Web 应用程序特别的简洁,只要创建 Web 应用程序时挑选的平台是基于 .NET Framework 3.5 的就能够创建使用 LINQ 的 Web 应用程序,如图 20-4 所示;图 20-4 挑选 .NET Framework 3.5 当创建一个基于系统.NET Framework 3.5的应用程序,系统就能够自动为应用程序创建LINQ 所需要的命名空间,示例代码如下所示;using System.Xml.Linq; LINQ 所需要的基础类和枚举,在/使用 LINQ 命名空间using System.Linq; /使用 LINQ 命名空间上述命名空间供应了应用程序中使用ASP.NET 应用程序中就能够使用 LINQ 查询语句进行查询,示例代码如下所示;protected void Page_Loadobject sender, EventArgs e string str = " 我爱 C#", " 我喜爱 C#", " 我做 C# 开发 ", "基于 .NET 平台 ", "LINQ 应用 " ; /数据集var s = from n in str where n.Contains"C#" select n; /执行 LINQ 查询foreach var t in s /遍历对象 Response.Writet.ToString + "<br/>" /输出查询结果 上述代码在ASP.NET 页面中执行了一段LINQ 查询,查询字符串中包含“C#” 的字符串,运行后如图 20-5 所示;495 名师归纳总结 - - - - - - -第 5 页,共 18 页精选学习资料 - - - - - - - - - 图 20-5 ASP.NET 执行 LINQ 查询在 ASP.NET 中能够使用 LINQ 进行数据集的查询, Visual Studio 2022 已经将 LINQ 整合成为编程语言中的一部分,基于 .NET Framework 3.5 的应用程序都可以使用 LINQ 特性进行数据拜访和整合;20.2.2 基本的 LINQ 数据查询使用 LINQ 能够对数据集进行查询,在 ASP.NET 中,可以创建一个新的 LINQ 数据库进行数据集查询,右击现有项目,单击【添加新项】选项,挑选【LINQ to SQL 类】选项,如图 20-6 所示;图 20-6 创建 LINQ to SQL 类创建一个 LINQ to SQL 类,能够映射一个数据库,实现数据对象的创建,如图 20-7 所示;创建一个 LINQ to SQL 类后, 可以直接在服务资源治理器中拖动相应的表到 所示;LINQ to SQL 类文件中, 如图 20-8496 名师归纳总结 - - - - - - -第 6 页,共 18 页精选学习资料 - - - - - - - - - 图 20-7 服务资源治理器图 20-8 拖动一个表开发人员能够直接将服务资源治理器中的表拖动到 LINQ to SQL 类中,在 LINQ to SQL 类文件中就会出现一个表的视图;在视图中,开发人员能够在视图中添加属性和关联,并且能够在 LINQ to SQL 类文件中可以设置多个表,进行可视化关联操作;创建一个 LINQ to SQL 类文件后, LINQ to SQL 类就将数据进行对象化,这里的对象化就是以面对对象的思想针对一个数据集建立一个相应的类,开发人员能够使用 LINQ to SQL 创建的类进行数据库查询和整合操作,示例代码如下所示;protected void Page_Loadobject sender, EventArgs e MyDataDataContext data = new MyDataDataContext; /使用 LINQ 类var s = from n in data.mynews where n.ID=1 select n; /执行查询foreach var t in s /遍历对象 Response.Writet.TITLE.ToString + "<br/>" /输出对象 上述创建了一个 MyData.dbml 的 LINQ to SQL 文件,开发人员能够直接使用该类的对象供应数据操作;上述代码使用了 LINQ to SQL 文件供应的类进行数据查询,LINQ 查询语句示例代码如下所示;var s = from n in data.mynews where n.ID=1 select n; /编写查询语句上述代码使用了 LINQ 查询语句查询了一个 mynews 表中 ID 为 1 的行,使用 LINQ to SQL 文件提供的对象能够快速的进行数据集中对象的操作;创建一个 MyData.dbml 的 LINQ to SQL 文件,其中MyDataDataContext 为类的名称,该类供应 LINQ to SQL 操作方法,示例代码如下所示;MyDataDataContext data = new MyDataDataContext; /使用 LINQ 类上述代码使用了 LINQ to SQL 文件供应的类创建了一个对象 data,data 对象包含数据中表的集合,通过“.” 操作符可以挑选相应的表,示例代码如下所示;data.mynews /挑选相应表使用 LINQ 查询后运行结果如图 20-9 所示;497 名师归纳总结 - - - - - - -第 7 页,共 18 页精选学习资料 - - - - - - - - - 图 20-9 LINQ 执行数据库查询使用 LINQ 技术能够便利的进行数据库查询和整合操作,LINQ 不仅能够实现类似 SQL 语句的查询操作,仍能够支持 .NET 编程方法进行数据查询条件语句的编写;使用 LINQ 技术进行数据查询的次序如下所示:创建 LINQ to SQL文件:创建一个LINQ to SQL类文件进行数据集封装;拖动数据表:将数据表拖动到LINQ to SQL 类文件中,可以进行数据表的可视化操作;使用 LINQ to SQL类文件:使用LINQ to SQL类文件供应的数据集的封装进行数据操作;使用 LINQ to SQL 类文件能够极快的创建一个LINQ 到 SQL 数据库的映射并进行数据集对象的封装,开发人员能够使用面对对象的方法进行数据集操作并供应快速开发的解决方案;20.2.3 IEnumerable和 IEnumerable<T> 接口,它答应开发人员定义foreach 语句IEnumerable 和 IEnumerable<T> 接口在 .NET 中是特别重要的接口功能的实现并支持非泛型方法的简洁的迭代,IEnumerable 和 IEnumerable<T> 接口是 .NET Framework 中最基本的集合拜访器,这两个接口对于 LINQ 的懂得是特别重要的;在面对对象的开发过程中,经常需要创建如干对象,并进行对象的操作和查询,在创建对象前,首先需要声明一个类为对象供应描述,示例代码如下所示;using System; using System.Collections.Generic; using System.Linq; /使用 LINQ 命名控件using System.Text; namespace IEnumeratorSample class Person /定义一个 Person 类 public string Name; /定义 Person 的名字 public string Age; /定义 Person 的年龄public Personstring name, string age /为 Person 初始化(构造函数)Name = name; /配置 Name 值Age = age; /配置 Age 值 上述代码定义了一个Person 类并抽象一个Person 类的属性,这些属性包括Name 和 Age ;Name 和498 名师归纳总结 - - - - - - -第 8 页,共 18 页精选学习资料 - - - - - - - - - Age 属性分别用于描述 Person 的名字和年龄,用于数据初始化;初始化之后的数据就需要创建一系列 Person 对象,通过这些对象的相应属性能够进行对象的拜访和遍历,示例代码如下所示;class Program static void Mainstring args Person per = new Person2 /创建并初始化2 个 Person 对象 new Person"guojing","21", /通过构造函数构造对象 new Person"muqing","21", /通过构造函数构造对象; foreach Person p in per /遍历对象 Console.WriteLine"Name is " + p.Name + " and Age is " + p.Age; Console.ReadKey; 上述代码创建并初始化了 2 个 Person 对象,并通过 foreach 语法进行对象的遍历;但是上述代码是 在数组中进行查询的,就是说假如要创建多个对象,就必需创建一个对象的数组,如上述代码中的 Per变量,而假如需要直接对对象的集合进行查询,却不能够实现查询功能;例如增加一个构造函数,该构造函数用户构造一组 Person 对象,示例代码如下所示;private Person per; public PersonPerson array /重载构造函数 ,迭代对象per = new Personarray.Length; /创建对象for int i = 0; i < array.Length; i+ /遍历初始化对象 peri = arrayi; /数组赋值 上述构造函数动态的构造了一组People 类的对象,那么应当也能够使用foreach 语句进行遍历,示例代码如下所示;Person personlist = new Personper; /创建对象foreach Person p in personlist /遍历对象 Console.WriteLine"Name is " + p.Name + " and Age is " + p.Age; 在 上 述 代 码 的 foreach 语 句 中 , 直 接 在 Person 类 的 集 合 中 进 行 查 询 , 系 统 就 会 报 错“ConsoleApplication1.Person ” 不包含“GetEnumerator ” 的公共定义,因此 foreach 语句不能作用于“ ConsoleApplication1.Person ” 类型的变量, 由于 Person 类并不支持foreach 语句进行遍历; 为了让相应的类能够支持foreach 语句执行遍历操作,就需要实现派生自类IEnumerable 并实现 IEnumerable 接口,示例代码如下所示;public IEnumerator GetEnumerator /实现接口 return new GetEnum_people; 为了让自定义类型能够支持foreach 语句,就必需对Person 类的构造函数进行编写并实现接口,示499 名师归纳总结 - - - - - - -第 9 页,共 18 页精选学习资料 - - - - - - - - - 例代码如下所示;class Person:IEnumerable /派生自 IEnumerable, 同样定义一个Personl 类 public string Name; /创建字段public string Age; /创建字段public Personstring name, string age /字段初始化 Name = name; /配置 Name 值Age = age; /配置 Age 值 public IEnumerator GetEnumerator /实现接口 return new PersonEnumper; /返回方法 上述代码重构了 Person 类并实现了接口,接口实现的具体方法如下所示;class PersonEnum : IEnumerator /实现 foreach 语句内部 ,并派生public Person _per; /实现数组int position = -1; /设置“ 指针”public PersonEnumPerson list _per = list; /实现 list public bool MoveNext /实现向前移动 position+; /位置增加return position < _per.Length; /返回布尔值 public void Reset /位置重置 position = -1; /重置指针为 -1 public object Current /实现接口方法 get try return _perposition; /返回对象 catch IndexOutOfRangeException /捕捉反常 throw new InvalidOperationException; /抛出反常信息 上述代码实现了foreach 语句的功能,当开发Person 类初始化后就可以直接使用Personal 类对象的集合进行 LINQ 查询,示例代码如下所示;500 名师归纳总结 - - - - - - -第 10 页,共 18 页精选学习资料 - - - - - - - - - static void Mainstring args Person per = new Person2 /同样初始化并定义2 个 Person 对象 new Person"guojing","21", /构造创建新的对象new Person"muqing","21", /构造创建新的对象; Person personlist = new Personper; /初始化对象集合 foreach Person p in personlist /使用 foreach 语句Console.WriteLine"Name is " + p.Name + " and Age is " + p.Age; Console.ReadKey; 从上述代码中可以看出,初始化 Person 对象时初始化的是一个对象的集合,在该对象的集合中可以通过 LINQ 直接进行对象的操作, 这样做即封装了 Person对象也能够让编码更加易读;在 .NET Framework 3.5 中,LINQ 支持数组的查询,开发人员不必自己手动创建IEnumerable 和 IEnumerable<T> 接口以支持某个类型的 foreach 编程方法,但是 IEnumerable 和 IEnumerable<T> 是 LINQ 中特别重要的接口, 在 LINQ中也大量的使用 IEnumerable 和 IEnumerable<T> 进行封装,示例代码如下所示;public static IEnumerable<TSource> Where<TSource> this IEnumerable<TSource> source,Func<TSource, Boolean> predicate /内部实现 foreach TSource element in source /内部遍历传递的集合 if predicateelement yield return element; /返回集合信息 上述代码为LINQ 内部的封装,从代码中可以看到,在LINQ 内部也大量的使用了IEnumerable 和IEnumerable<T> 接口实现 LINQ 查询; IEnumerable 原本就是 .NET Framework 中最基本的集合拜访器,而 LINQ 是面对关系 (有序 N 元组集合) 的,自然也就是面对 和 IEnumerable<T> 对 LINQ 的懂得是有肯定帮忙的;20.2.4 IQueryProvider和 IQueryable<T> 接口IEnumerable<T> 的,所以明白 IEnumerableIQueryable 和 IQueryable<T> 同样是 LINQ 中特别重要的接口,在 LINQ 查询语句中, IQueryable 和IQueryable<T> 接口为 LINQ 查询语句进行说明和翻译工作,开发人员能够通过重写 IQueryable 和IQueryable<T> 接口以实现用不同的方法进行不同的LINQ 查询语句的说明;IQueryable<T> 继承于 IEnumerable<T> 和 IQueryable 接口,在 IQueryable 中包括两个重要的属性,这两个属性分别为 Expression 和 Provider;Expression 和 Provider 分别表示猎取与 IQueryable 的实例关联的表达式目录树和猎取与数据源关联的查询供应程序,Provider 作为其查询的翻译程序实现 LINQ 查询语句的说明;通过 IQueryable 和 IQueryable<T> 接口,开发人员能够自定义 LINQ Provider ;留意: Provider 可以被看做是一个供应者,用于供应 LINQ 中某个语句的说明工具,在 LINQ 中通过编程的方法能够实现自定义 Provider;在 IQueryable 和 IQueryable<T> 接口中,仍需要另外一个接口,这个接口就是 IQueryProvider ,该接口用于分解表达式,实现 LINQ 查询语句的说明工作,这个接口也是整个算法的核心;IQueryable<T>接口在 MSDN 中的定义如下所示;501 名师归纳总结 - - - - - - -第 11 页,共 18 页精选学习资料 - - - - - - - - - public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable public interface IQueryable : IEnumerable Type ElementType get; /猎取元素类型 Expression Expression get; /猎取表达式 IQueryProvider Provider get; /猎取供应者 上述代码定义了IQueryable<T> 接口的规范, 用于保持数据源和查询状态,IQueryProvider 在 MSDN中定义如下所示;public interface IQueryProvider IQueryable CreateQueryExpression expression; /创建可执行对象 IQueryable<TElement> CreateQuery<TElement>Expression expression; /创建可执行对象 object ExecuteExpression expression; /运算表达式 TResult Execute<TResult>Expression expression; /运算表达式 IQueryProvider 用于 LINQ 查询语句的核心算法的实现,包括分解表达式和表达式运算等;为了能 够创建自定义 LINQ Provider ,可以编写接口的实现;示例代码如下所示;public IQueryable<TElement> CreateQue