1 / 44

第 18 章 数据访问的新利器 —— 语言集成查询技术

第 18 章 数据访问的新利器 —— 语言集成查询技术.

oberon
Télécharger la présentation

第 18 章 数据访问的新利器 —— 语言集成查询技术

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第18章 数据访问的新利器——语言集成查询技术 语言集成查询(Language Integrated Query,LINQ)是Visual Studio 2008和.NET Framework 3.5版中一项突破性的创新,它在对象领域和数据领域之间架起了一座桥梁。传统上,针对数据的查询都是以简单的字符串表示,而没有编译时类型检查或IntelliSense支持。此外,还必须针对不同的数据源学习不同的查询语言,如SQL数据库、XML文档、各种Web服务等。而LINQ引入了标准的、易于学习的查询和更新数据模式,可以对其技术进行扩展以支持几乎任何类型的数据存储。Visual Studio 2008包含LINQ Privider的程序集,这些程序集支持将LINQ与.NET Framework集合、SQL Server数据库、ADO.NET数据集和XML文档一起使用。

  2. 章节内容 • 18.1 什么是LINQ • 18.2 学习写自己的LINQ查询 • 18.3 LINQ to SQL

  3. 18.1 什么是LINQ • LINQ,是语言集成查询(Language Integrated Query)的简称,是 Visual Studio 2008 和.NET Framework 3.5版中一项突破性的创新。MicroSoft宣称LINQ在对象领域和数据领域之间架起了一座桥梁。

  4. 首先要说明什么是查询 • 查询是一种从数据源检索数据的表达式。现在,我们的程序中控制的数据可以属于不同的数据域。 • 例如,一个数组,一个对象图表(object graph),一个XML文件,一个数据库,一个文本文件,一个注册表值,一封电子邮件,简单对象访问协议(Simple Object Access Protocol)信息内容,一个微软的Excel表格等等,举不胜举。

  5. 不同数据域有不同的访问方法 • 当查询一个数据库时,我们会很自然地就用SQL。 • 当访问XML数据时,很自然地就用DOM或者XQuery。 • 为了定位某个对象图,遍历一个数组并且构建自己的算法。 • 使用特定的应用程序(APIs)来访问其他的数据域,比如说Office的Excel表格, • 最终的结果是,在访问不同的数据源时就有了不同的编程模型。

  6. LINQ试图统一这些不同数据源的不同访问方法!LINQ试图统一这些不同数据源的不同访问方法! • LINQ是一个编程模型,无论是访问文件、XML、数据库、注册表、事件日志、活动目录,还是第三方的数据,都可以使用统一的方法进行访问。 • LINQ可以与所有不同形态、不同大小的数据一起工作,允许在所有这些数据上执行查询、设置和转换。 • 而且LINQ是集成在.NET编程语言中的一种特性,已经成为编程语言的一个组成部分。

  7. 事实上,第10章介绍的Visual Studio.Net 2008在语言方面的新特性,包括扩展方法、匿名类型、Lambda表达式、查询表达式等,大部分都是为了支持LINQ而做出的。

  8. LINQ查询操作 • 由以下3个不同的操作步骤组成。 • 获取数据源。 • 创建查询。 • 执行查询。 • 而这3个步骤,实际上都是由LINQ提供程序来完成的。

  9. 4种提供程序 • LINQ to SQL • LINQ to XML • LINQ to Objects • LINQ to DataSet

  10. 18.2 学习写自己的LINQ查询 • 18.2.1 第一个LINQ查询 1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 2 Label1.Text = "" 3 ' 数据源 4 Dim numbers As Integer( ) = {0, 1, 2, 3, 4, 5, 6} 5 ' 创建查询(获取索引号为偶数的元素) 6 Dim numQuery = From num In numbers _ 7 Where num Mod 2 = 0 _ 8 Select num 9 ' 执行查询 10 For Each num In numQuery 11 Label1.Text &= num & vbCrLf 12 Next 13 End Sub

  11. 此示例将一个整数数组numbers用作数据源 • numQuery:查询变量,其本身不执行任何操作并且不返回任何数据。它只是存储在以后某个时刻执行查询时为生成结果而必需的信息。 • from子句:指定数据源。 • num:范围变量,表示数据源的后继元素 • where子句:应用筛选器。 • select子句:指定返回的元素的类型。

  12. 查询变量 • 在LINQ中,查询变量是任何存储查询而不是查询结果的变量。 • 更具体地说,查询变量始终是一个可枚举的类型,当在For each语句中或对其IEnumerator.MoveNext方法的直接调用中循环访问它时,它将产生一个元素序列。 • 上一个例子中的numQuery就是一个查询变量,简称查询。

  13. 查询表达式 • 查询表达式是用查询语法表示的查询。 • 由一组用类似于SQL或XQuery的声明性语法编写的子句组成。每个子句又包含一个或多个表达式,而这些表达式本身又可能是查询表达式或包含查询表达式。

  14. 查询表达式语法 • 查询表达式必须以From子句开头,并且必须以Select或Group子句结尾。 • 在第一个From子句和最后一个Select或Group子句之间,查询表达式可以包含一个或多个可选子句:Where、Orderby、Join、Let甚至附加的From子句。 • 还可以使用Into关键字使Join或Group子句的结果能够充当同一查询表达式中附加查询子句的源。

  15. From子句:指定数据源 From element [ As type ] In collection [ _ ] [, element2 [ As type2 ] In collection2 [ , ... ] ] • element是必需的,这是一个范围变量,用于循环访问集合的元素,必须为可枚举类型。该范围变量用于在查询循环访问collection时,引用collection的每个成员。 • type是可选的,用于指明element的类型。如果不指定type,则根据collection推断element的类型。 • collection是必需的。这是引用要查询的集合,必须为可枚举类型。

  16. Where子句:筛选数据 • Where子句用于执行筛选,筛选器指定要在结果序列中包含数据源中的哪些元素。Where子句的语法格式如下。 • Where condition • 其中,condition是一个表达式,该表达式的计算结果必须为Boolean值或Boolean值的等效值。如果条件的计算结果为True,则在查询结果中包含该元素;否则从查询结果中排除该元素。

  17. Order By子句:对数据进行排序 Order By orderExp1 [ Ascending | Descending ] [, orderExp2 [...] ] • 其中,orderExp1是必需的,这是当前查询结果中的一个或多个字段,用于标识对返回值进行排序的方式,字段名称必须以逗号(,)分隔; • 使用Ascending或Descending关键字可以指定对每个字段进行升序或降序排序。如果未指定Ascending和Descending关键字,则默认排序顺序为升序。排序顺序字段的优先级从左到右依次降低。

  18. Select子句:选择数据 • Select [ var1 = ] fieldName1 [, [ var2 = ] fieldName2 [...] ] • 其中,var1是可选的,可用于引用列表达式的结果的别名;fieldName1是必需的,是要在查询结果中返回的字段的名称。

  19. Group By子句:对数据进行分组 Group [ listField1 [, listField2 [...] ] By keyExp1 [, keyExp2 [...] ] Into aggregateList • listField1,listField2是可选的,用于指明查询变量的一个或多个字段,这些查询变量显式标识要包括在分组结果中的字段。如果未指定任何字段,则查询变量的所有字段都包括在分组结果中。

  20. keyExp1是必需的,这是一个表达式,标识用于确定元素的分组的键。可以指定多个键来指定一个组合键。keyExp1是必需的,这是一个表达式,标识用于确定元素的分组的键。可以指定多个键来指定一个组合键。 • keyExp2是可选的,是一个或多个附加键,与keyExp1组合在一起,创建一个组合键。 • aggregateList是必需的,是一个或多个表达式,标识如何对组进行聚合。若要为分组结果标识一个成员名称,可以使用Group关键字。

  21. Let子句:存储查询结果 • Let variable = expression [, ...] • 其中,variable是必需的,这是一个别名,可用于引用所提供的表达式的结果;expression是必需的,这是一个将进行计算并赋值给指定变量的表达式。

  22. 执行查询 • 查询执行与查询创建是分开的。创建查询后,其执行由不同的机制触发。 • 可在定义查询后立即执行查询(立即执行) • 也可以存储查询定义,并在以后执行查询(延迟执行)。

  23. 立即执行 • 默认情况下,创建查询后,查询本身并不立即执行。相反,查询定义将存储在用于引用查询结果的变量中。当以后在代码中访问查询结果变量时(如在For…Next循环中),将执行该查询,此过程称为延迟执行。之前我们看到的例子都是延迟执行方式。

  24. 延迟执行 • 查询还可以在定义后执行,这称为立即执行。立即执行可以通过应用要求访问查询结果的各个元素的方法来触发,这是包含聚合函数(如Count、Sum、Average、Min或Max)的结果。

  25. 18.3 LINQ to SQL • LINQ to SQL全称为基于关系数据的.NET语言集成查询,是.NET Framework 3.5版的一个组件,提供了用于将关系数据作为对象管理的运行时基础结构。

  26. LINQ to SQL编程接口集中在System.Data.Linq.dll程序集中,要想使用LINQ to SQL,必须在项目中引用该程序集,命名空间为“System.Data.Linq”。

  27. 示例数据库结构

  28. 18.3.1 创建对象模型 • 创建LINQ to SQL对象模型是使用LINQ to SQL的第一步,也是最重要的一步。对象模型实际是数据库的一个映射关系和操作集合。

  29. 3种创建对象模型的方式 • (1)对象关系设计器。 • (2)SQLMetal代码生成工具。 • (3)代码编辑器。

  30. 第一种方式 • 首先需要建立与数据库的连接。可以单击菜单栏中的【工具】→【连接到数据库】来连接到你的数据库或者在【服务器资源管理器】窗口中建立数据库连接。

  31. 之后,单击菜单栏中的【项目】→【添加新项】命令,打开【添加新项-LINQtoSQLExample】窗口,在【模板】列表框中选择【LINQ to SQL类】,在【名称】文本框中输入“Student.dbml”。 • 其中,扩展名dbml的全称为Database Mark Language,即数据库描述语言,是一种xml格式的文档,用来描述数据库。

  32. 单击【添加】按钮以后,读者会看到dbml文件的窗口与以前我们所见到的设计窗口有些不一样。单击【添加】按钮以后,读者会看到dbml文件的窗口与以前我们所见到的设计窗口有些不一样。 • 该设计窗口分了两部分:左边是数据类的可视化窗口,右边是方法的创建窗口

  33. 我们将StudentInfo表从【服务器资源管理器】窗口中直接拖曳到右边的数据类可视化窗口,即可创建一个数据类。我们将StudentInfo表从【服务器资源管理器】窗口中直接拖曳到右边的数据类可视化窗口,即可创建一个数据类。

  34. 查看代码可以看到,生成了一个StudentInfoDataContext类。该类继承自继承自System.Data.Linq.DataContext。查看代码可以看到,生成了一个StudentInfoDataContext类。该类继承自继承自System.Data.Linq.DataContext。 • DataContext类是一个LINQ to SQL类,它充当SQL Server数据库与映射到该数据库的LINQ to SQL实体类之间的管道 • 生成的实体类代码如下。 1 Partial Class StudentInfoDataContext 2 3 End Class

  35. 18.3.2 获取数据 下面代码是窗体的Load事件过程,使用LINQ获取数据并输出。 1 Imports System.Data.Linq 2 Public Class Form1 3 4 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 5 ' 实例化LINQ to SQL对象 6 Dim db As New StudentInfoDataContext( ) 7 ' 得到一个表 8 Dim studentList As Table(Of StudentInfo) = db.GetTable(Of StudentInfo)( ) 9 ' LINQ查询 10 Dim query = From student In studentList _ 11 Select student.StuNum, student.StuName 12 ' 输出 13 For Each student In query 14 Label1.Text &= "学号 = " & student.StuNum & ", 姓名 = " & _ 15 student.StuName & vbCrLf 16 Next 17 End Sub 18 End Class

  36. 使用DataGridView控件来进行数据显示。 1 ' 实例化LINQ对象 2 Dim db As New StudentInfoDataContext() 3 ' 得到一个表 4 Dim studentList As Table(Of StudentInfo) = db.GetTable(Of StudentInfo)() 5 ' LINQ查询 6 Dim query = From student In studentList _ 7 Select student.StuNum, student.StuName 8 ' 绑定数据源 9 DataGridView1.DataSource = query

  37. 18.3.3 添加数据 • 如果想要往数据库表中添加一条记录,只要向已创建的表对象模型添加一个新学生对象,然后调用StudentInfoDataContext对象的SubmitChanges方法即可。

  38. 下面代码实现了记录的添加。 1 Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As _ 2 System.EventArgs) Handles btnAdd.Click 2 Dim db As New StudentInfoDataContext( ) 3 ' 新学生 4 Dim newStudent As New StudentInfo 5 newStudent.StuNum = "20083201" 6 newStudent.StuName = "李克" 7 ' 将新学生添加到Insert命令中 8 db.StudentInfo.InsertOnSubmit(newStudent) 9 ' 执行 10 db.SubmitChanges( ) 11 End Sub

  39. 18.3.4 更新数据 • 如果要更新某一条记录内容,首先需要检索到该项,然后直接在对象模型中编辑它。在修改了该对象之后,调用StudentInfoDataContext对象的SubmitChanges方法以更新数据库。

  40. 下面代码实现记录的更新。 1 Dim db As new StudentInfoDataContext( ) 2 ' 找到要修改的记录 3 Dim studentToUpdate = _ 4 from stu in db.StudentInfo _ 5 where stu.StuNum="20083201" _ 6 select stu 7 ' 对找到的记录进行修改 8 for each student in studentToUpdate 9 student.Sex = "男" 10 student.Age=21 11 student.Major="数学" 12 student.Class="0821" 13 Next 14 ' 提交修改 15 db.SubmitChanges( );

  41. 18.3.5 删除数据 • 如果要删除某条记录,要先从其所属集合中移除,然后调用StudentInfoDataContex对象的SubmitChanges方法以提交所做的更改。注意,LINQ to SQL无法识别级联删除操作。

  42. 下面代码实现记录的删除。 1 Dim db As new StudentInfoDataContext( ) 2 ' 找到要删除的记录 3 Dim studentToUpdate = _ 4 from stu in db.StudentInfo _ 5 where stu.StuNum= "20080002" _ 6 select stu 7 ' 如果找到了符合条件的记录则进行删除 8 for each student in studentToUpdate 9 db.StudentInfo.DeleteOnSubmit(student) 10 Next 11 ' 提交删除 12 db.SubmitChanges( )

More Related