1、第9章 ADO.NET与数据操作,9.1 ADO.NET简介 9.2 数据库与数据库访问工具 9.3 ADO.NET数据访问对象 9.4 数据绑定技术 9.5 DataGridView控件 9.6 数据处理 9.7 存储过程 9.8 语言集成查询(LINQ),9.1 ADO.NET简介,ADO.NET是在ADO(ActiveX Data Objects)基础上发展的新一代数据存取技术,是微软.NET平台下提出的新的数据访问模型。ADO.NET设计了一系列对各类数据的访问形式,并提供了对应的类,类中提供了与对应数据交互的属性和方法,我们可以通过这些属性和方法对各种数据进行存取操作。,数据访问操作
2、的发展,采用ODBC(开发式数据互连)数据访问形式。这种访问方式的前提是,只要公司提供某个数据库的数据驱动程序,就可以在程序中对这个数据库操作。但是这种方式只能对结构化数据操作,对于非结构化数据无能为力。 采用OLE DB数据访问形式。该方式设计了一个抽象层,由抽象层负责对不同类型的数据提供统一的形式,程序与数据源打交道均经过抽象层。达到了对结构化、非结构化数据均能按统一的方式进行操作。 采用ADO数据模型。该模型在OLE DB的基础上又重新设计了访问层,对高级语言编写的程序提供了统一的以“行”为操作目标的数据访问形式。 采用ADO.NET数据访问模型。该模型重新整合OLE DB和ADO,并在
3、此基础上构造了新的对象模型。该模型既提供了保持连接的数据访问形式,又提供了松耦合的、以DataSet对象为操作目标的数据访问形式。,ADO.NET数据访问模型,VS2008开发环境下使用的是ADO.NET 2.0。 在ADO.NET 2.0中,SQL数据提供程序使用统一的SQL数据访问模型实现对各种使用SQL语句的数据库的数据访问支持。例如Oracle、SQL Server、DB2、Access等。,9.2 数据库与数据库访问工具,9.2.1 SQL Server 数据库的分类VS2008中有3种与SQL Server数据库的连接形式,分别为“SQL Server”、“SQL Server C
4、ompact 3.5”和“SQL Server数据库文件”。 1Microsoft SQL Server该选项用于和远程服务器上的数据库连接。 2Microsoft SQL Server数据库文件该选项用于和SQL Server Express数据库文件建立连接。本章的所有例子均用SQL Server Express来讲解。,9.2.1 SQL Server 数据库的分类,3Microsoft SQL Server Compact 3.5SQL Server Compact 3.5是一个更简单的SQL Server数据库版本,数据库扩展名为.sdf,该版本是基于文件的数据库,而不是基于服务的数
5、据库,这种类型的数据库一般用于移动设备应用程序。 4本地数据库文件不论是哪种数据库文件,只要是保存在本地计算机上,就称其为本地数据库文件。在“新建项”模板中,本地数据库文件又分为“本地数据库”和“基于服务的数据库”,模板中的“本地数据库”是指SQL Server Compact 3.5的.sdf文件,“基于服务的数据库”是指SQL Server Express的.mdf文件。 5数据库文件的属性设置项目中本地数据库文件的【复制到输出目录】属性的默认值如下:(1)对于.sdf文件,其默认值为“如果较新则复制”。(2)对于.mdf文件,其默认值为“始终复制”。,9.2.2 数据访问可视化工具,1服
6、务器资源管理器 2数据集设计器 3数据源,本章选用示例数据库,数据库MyDatabase.mdf 数据表:见P235页定义 MyTable1学院编码对照表 MyTable2基本情况表 MyTable3家庭成员表 数据类型说明: char、Varchar Nchar、Nvarchar Datetime Image、Binary、VarBinary Text、NText,9.3 ADO.NET数据访问对象,ADO.NET常用的对象模型:(1) Connection对象(2) Command对象(3) DataReader对象(4) DataAdapter对象(5) Parameter对象(6) T
7、ransaction对象 这些对象提供了对数据库的各种不同的访问功能 对于不同的数据库,区别仅是前缀不同,例如:SQL Server数据库:SqlConnection、SqlDataAdapterOracle数据库:OracleConnection、OracleDataAdapter,9.3.1 SqlConnection对象,ADO.NET使用SqlConnection对象与SQL Server进行连接。 连接字符串的常用形式有两种: (1)使用Windows集成安全身份验证,例如:string connectionString = “Integrated Security=SSPI; Da
8、tabase=MyDatabase.mdf; Server=localhost;“;(2)使用用户名、密码形式,例如: string connectionString = “ server=localhost; uid=sa; pwd=123; database=MyDatabase.mdf”; 但是这种连接方式的安全性不高,比较容易受到黑客的攻击,9.3.1 SqlConnection对象(续),如果与SQL Server Express Edition创建连接,可以直接使用附加数据库名的方式。连接字符串的一般形式为:string connectionString =“Data Source
9、=.SQLEXPRESS; AttachDbFilename=|DataDirectory|DatabaseName;“ + “Integrated Security=True; Connect Timeout=60; User Instance=True“例如,下一页,9.3.1 SqlConnection对象(续),string connectionString =“Data Source=.SQLEXPRESS; AttachDbFilename=|DataDirectory|MyDataBase.mdf; “+ “Integrated Security=True; Connect Ti
10、meout=60; User Instance=True“;SqlConnection conn = new SqlConnection(connectionString);实际上,连接字符串是可以自动生成的。在使用创建数据库之后,系统会自动生成一个连接字符串,并保存到配置文件中 例如:Properties.Settings.Default.MyDatabaseConnectionString 确定连接字符串后,就可以创建SqlConnection对象。,9.3.1 SqlConnection对象(续),为了简化书写,还需要在代码中添加对命名空间的引用:using System.Data.Sq
11、lClient;可通过连接字符串直接创建SqlConnection对象,例如:SqlConnection conn = new SqlConnection(connString);或者:SqlConnection conn = new SqlConnection();conn.ConnectionString = connString;,9.3.2 SqlCommand对象,在ADO.NET中,有两种操作数据库的方式: (1)采用无连接的方式。 (2)采用保持连接的方式。 不论采用哪种方式,都可以通过SqlCommand对象提供的方法传递对数据库操作的命令,并返回命令执行的结果。,9.3.2
12、SqlCommand对象(续),在保持连接的方式下操作数据库的一般步骤为: 1) 创建SqlConnection的实例; 2) 创建SqlCommand的实例; 3) 打开连接; 4) 执行命令; 5) 关闭连接。 SqlCommand对象提供了多种完成对数据库操作的方法。常用有:1. ExecuteNonQuery该方法执行SQL语句的结果,但不返回命令执行的表数据,仅返回操作所影响的行数。2.ExecuteReader:返回一个SqlDataReader对象。,9.3.2 SqlCommand对象(续),3. ExecuteScaler()该方法用于执行SELECT查询,得到的返回结果为一
13、个值的情况,比如使用count函数求表中记录个数或者使用sum函数求和等。,SQL语句中使用参数,SqlParameter对象 表示SqlCommand的参数。 其中参数名称不区分大小写。 使用方法/声明一个参数SqlParameter parameter = cmd.Parameters.Add( “CategoryName“, SqlDbType.NVarChar, 15); /为参数赋值parameter.Value = “Beverages“; 或者:cmd.Parameters.Add( “CategoryName“, SqlDbType.NVarChar, 15);cmd.Para
14、meters“CategoryName”.Value= “Beverages“;,9.3.2 SqlCommand对象(续),【例9-2】演示SqlCommand对象的用法。,9.3.3 SqlDataAdapter对象,SqlDataAdapter对象通过无连接的方式完成数据库和本地DataSet之间的交互。一般步骤: 1) 创建SqlConnection的实例; 2) 创建SqlDataAdapter的实例,需要的话,根据select语句生成其他SQL语句; 3) 创建DataSet的实例; 4) 使用Fill方法将数据库中的表填充到DataSet表中; 5) 利用DataGridView
15、或者其他控件对象编辑或显示数据; 6) 需要的话,使用Update方法更新数据库。,9.3.3 SqlDataAdapter对象(续),SqlDataAdapter对象通过SelectCommand、Insert Command、UpdateCommand和DeleteCommand属性为后台数据库提供对应的操作命令,并传递需要的参数。 一般情况下,只需要提供SELECT语句和连接字符串创建SqlDataAdapter对象,然后利用SqlCommandBuilder对象生成InsertCommand、UpdateCommand和DeleteCommand属性。,9.3.3 SqlDataAda
16、pter对象(续),【例9-3】根据选择的表名打开数据库表,并将表中数据通过DataGridView显示出来。 设计界面如下:,9.3.4 DataTable对象,ADO.NET可以在与数据库断开连接的方式下通过DataSet或DataTable对象进行数据处理,当需要更新数据时才重新与数据源进行连接,并更新数据源。 DataTable对象表示保存在本机内存中的表,它提供了对表中行列数据对象的各种操作。可以直接将数据从数据库填充到DataTable对象中,也可以将DataTable对象添加到现有的DataSet对象中。,9.3.4 DataTable对象(续),在断开连接的方式下,DataSe
17、t对象提供了和关系数据库一样的关系数据模型,代码中可以直接访问DataSet对象中的DataTable对象,也可以添加、删除DataTable对象。,9.3.4 DataTable对象(续),【例9-4】自定义一个DataTable对象,直接创建行列信息,并在DataGridView中显示创建的内容。,9.3.5 DataSet对象,1. 创建DataSet对象使用创建的DataSet对象可以完成各种数据操作。 注意: 利用向导生成的数据库数据源是一个强类型的DataSet以及一对或多对强类型的DataTable和TableAdapter的组合。 2. 填充DataSet对象创建DataSet
18、后,就可以使用SqlDataAdapter对象把数据导入到DataSet对象中,比如通过Fill方法将数据填充到DataSet中的某个表中。,9.4 数据绑定技术,数据绑定是指在程序运行时,窗体上的控件自动将其属性和数据源关联在一起。数据绑定技术是数据操作中使用最频繁的技术,利用数据绑定技术能极大地提高项目开发的效率。 简单数据绑定与复杂数据绑定。 数据源组件。 导航控件。,9.4.1 简单数据绑定与复杂数据绑定,Windows窗体提供了两种类型的数据绑定:简单数据绑定和复杂数据绑定。 1.简单数据绑定指将一个控件的某个属性绑定到单个值。这种类型的绑定适用于只显示单个值的控件,一般将这些控件绑
19、定到数据库中某个记录的一个字段。比如TextBox等控件。 2.复杂数据绑定指将一个控件绑定到多个值。这种类型的绑定适用于显示多个值的控件,例如DataGridView控件、ListBox控件和ComboBox控件等。,9.4.1 简单数据绑定与复杂数据绑定,从实现数据绑定的方式上,有3种实现方法: 在设计界面下通过鼠标拖放实现常用属性的数据绑定; 在设计界面下设置控件的DataBindings属性,然后利用可视化界面实现各种属性的数据绑定; 直接编写代码实现数据绑定。,9.4.1 简单数据绑定与复杂数据绑定,实际上,不论采用哪种方式,从本质上来讲,都是利用BindingSource组件来实现
20、数据绑定的。 1通过鼠标拖放实现数据绑定 对于比较简单的数据库应用,大部分情况下,都可以在设计界面下通过鼠标拖放完成绑定功能。常用方式有: 将【数据源】中的数据表字段直接拖放到设计窗体上,让系统自动创建和该表字段绑定的控件。 将【数据源】中的表直接拖放到设计窗体上,让系统自动创建和该表绑定的控件。 将【数据源】中的字段直接拖放到窗体上已有的控件上,该控件即自动绑定到拖放的表字段。,9.4.1 简单数据绑定与复杂数据绑定,2通过设置控件的属性实现数据绑定工具箱中提供的每个控件,都有一个【DataBindings】属性,用于绑定数据源。 利用它实现数据绑定的步骤如下。 (1)在窗体中,选择该控件并
21、显示属性窗口,然后展开【(DataBindings)】属性,此时即看到与控件对应的默认绑定属性。实际上,用鼠标拖放所绑定的属性都是自动绑定到默认的属性。 (2)单击【(Advanced)】属性右边的“”按钮,显示“格式设置和高级绑定”对话框,再此对话框中,选择要绑定的数据源和被绑定的属性即可。,9.4.1 简单数据绑定与复杂数据绑定,3直接编写代码实现数据绑定 如果程序员希望灵活地控制绑定的数据库表字段,也可以直接编写绑定代码。采用这种方式实现数据绑定的步骤如下。 从【工具箱】中拖放一个BindingSource组件、一个自动生成的强类型的DataSet组件、一个强类型的DataAdapter
22、组件到设计窗体上。如果窗体上已经有这些对象,则不需要此步骤; 从【工具箱】中拖放一个被绑定的控件到设计窗体上,修改控件的【Name】属性为有意义的名称。 添加绑定代码。,9.4.1 简单数据绑定与复杂数据绑定,【例9-5】演示常用控件的数据绑定方法。,9.4.2 BindingSource组件,1、BindingSource组件用统一的数据绑定中间层绑定不同数据源。用法: (1)将BindingSource组件绑定到实际数据源(2)将控件绑定的数据源设置为BindingSource组件,9.4.2 BindingSource组件(续),BindingSource组件常用的属性主要有:1) Da
23、taSource属性:获取或设置绑定到BindingSource的数据源。2) Sort属性:获取或设置数据源中各列的排序字符串。3) Filter属性:获取或设置数据源中记录筛选条件字符串。 4) Current属性:指绑定列表中的当前项。,9.4.2 BindingSource组件(续),【例9-6】设计一个Windows应用程序,显示本机当前支持的所有字体。 左图为设计界面,右图为运行效果。,9.4.3 BindingNavigator组件,BindingNavigator组件同时提供了两种功能: 提供了对窗体中的数据进行导航控制和常用数据操作的方法 提供了一个ToolStrip控件形式
24、的导航条。 常用属性: 1) BindingSource:指定组件所要绑定的BindingSource对象。 2) Dock:确定BindingNavigator组件提供的ToolStrip在窗体设计器中的位置。,9.4.3 BindingNavigator组件,【例9-7】设计一个Windows窗体应用程序,自动将MyDatabase.mdf中包含的所有表的名称显示出来供用户选择,同时在界面中提供记录导航和添加、删除等功能,并能保存修改后的结果。 左图为设计效果,右图为运行效果。,9.5 DataGridView控件,用途:显示与编辑二维表数据 1.默认功能 如果绑定了数据源,则会自动为数据
25、源中的每个字段单独创建一列。 自动使用字段名称作为列标题。列标题是固定的,即在列表中向下移动滚动条时列标题不会滚动出视图。 支持自动排序。在列标题中单击或双击,该字段中的值就会按升序或降序排序。字母顺序区分大小写。 单击DataGridView左上角的方块可以选择整个表。 支持自动调整大小功能。在标题之间的列分隔符上双击,该分隔符左边的列就会自动按照单元格的内容展开或收缩。,9.5 DataGridView控件,2.绑定数据源 利用DataGridView控件操作数据库中的数据时,一般都是利用数据绑定技术来实现。步骤如下。 (1)将数据库中的表数据读到DataSet或者DataTable中;
26、(2)创建一个BindingSource对象,将BindingSource对象绑定到DataSet或者直接绑定到DataTable; (3)将DataGridView绑定到BindingSource对象。,9.5 DataGridView控件,【例9-8】演示DataGridView常用功能。 设计界面如下:,9.5 DataGridView控件,3.标题及行列控制 DataGridView提供了两个关键集合Columns和Rows,用于处理整个数据集。其中Columns是DataGridViewColumn对象的集合,Rows是DataGridViewRow对象的集合,每个DataGridV
27、iewRow对象又都包含一组DataGridViewCell对象。,9.5 DataGridView控件,【例9-9】在例9-8的程序中,实现“标题及行列控制”中的所有按钮功能。 标题控制 隔行显示背景色 防止添加和删除行 判断用户同时选择了哪些行 显示/隐藏指定的列 将某些列设为只读 更改列的显示顺序 固定左边的某些列 自动调整各列宽度,9.5 DataGridView控件,4.单元格控制 【例9-10】在例9-8的程序中,实现“单元格控制”中的所有按钮功能。 判断用户同时选择了哪些单元格 突出显示单元格 日期时间显示格式控制 在单元格中嵌入下拉列表框,9.5 DataGridView控件,
28、5.异常处理 【例9-11】在例9-8的程序中,实现“常用事件”中的所有按钮功能。 CellFormatting事件 DataError事件 CellValidating事件,9.6 数据处理,9.6.1 图像数据处理 1利用SQL语句实现图像导入导出 (1)导入图片 string connString = Properties.Settings.Default.MyDatabaseConnectionString; string sql = “update MyTable2 set 照片=Photo where 姓名=StudentName“; using (SqlConnection co
29、nn = new SqlConnection(connString) SqlCommand cmd = new SqlCommand(sql, conn);cmd.Parameters.Add(“StudentName“, SqlDbType.NVarChar).Value = “王小琳“;OpenFileDialog openFileDialog1 = new OpenFileDialog( );if (openFileDialog1.ShowDialog( ) = DialogResult.OK)Stream myStream = openFileDialog1.OpenFile( );b
30、yte bt = new bytemyStream.Length;myStream.Read(bt, 0, (int)myStream.Length);cmd.Parameters.Add(“Photo“, SqlDbType.Image).Value = bt;conn.Open( );cmd.ExecuteNonQuery( );myStream.Dispose( ); ,9.6.1 图像数据处理,(2)导出图片 string connString = Properties.Settings.Default.MyDatabaseConnectionString; string sql =
31、“select 照片 from MyTable2 where 姓名=StudentName“; using (SqlConnection conn = new SqlConnection(connString) SqlCommand cmd = new SqlCommand(sql, conn);cmd.Parameters.Add(“StudentName“, SqlDbType.NVarChar).Value = “王小琳“;conn.Open( );SqlDataReader dr = cmd.ExecuteReader( );if (dr.Read( )if (dr0.GetType(
32、 ) != typeof(DBNull)byte bs = (byte)dr0;MemoryStream ms = new MemoryStream(bs);Bitmap image = new Bitmap(ms);Graphics g = this.CreateGraphics( );g.DrawImage(image, 10, 10);g.Dispose( );ms.Dispose( );,9.6.1 图像数据处理,2利用PictureBox控件实现图像导入导出 【例9-12】演示数据库中图像数据的处理方法。 设计界面如下:,9.6.2 关联表数据处理,【例9-13】利用DataGrid
33、View完成对学生人员基本信息的所有数据编辑操作,包括添加、删除、保存以及对照片和家庭人员情况的处理,同时显示学院编码和编码对应的名称,当用户选择名称时,自动修改对应的编码。 设计界面:,9.6.2 关联表数据处理,运行界面:,9.7 存储过程,存储过程是指将常用的或复杂的数据库操作,预先用SQL语句写好并用一个指定的名称存储起来,以后需要完成与已定义好的存储过程的功能相同的数据库操作时,只需调用存储过程的名称即可。存储过程具有以下优点:存储过程编辑器事先对存储过程进行了语法检查处理,避免了因SQL语句语法不正确引起运行时出现异常的问题;只在保存存储过程时数据库服务器才进行编译。,9.7 存储
34、过程(续),在定义或编辑存储过程的时候,可以直接检查运行结果是否正确,提高了开发效率;避免了查询字符串中包含单引号可能会出现的问题;一个项目中可能会多处用到相同的sql语句,使用存储过程便于重用;修改灵活方便,当需要修改完成的功能时,只需要修改定义的存储过程即可,而不必单独修改每一个引用。,9.7 存储过程,1.创建和修改存储过程 在VS2008开发环境下,利用【服务器资源管理器】,除了可以直接创建SQL Server数据库和数据库中的表以外,还可以直接创建或修改存储过程。 2.在存储过程中定义参数 存储过程可以带参数,也可以不带参数。 利用SqlCommand对象的Parameters属性提
35、供的功能,可以传递执行存储过程所用的参数。SQL Server的存储过程如果带参数,参数名必须以“”为前缀。 参数的方向: Input:参数是输入参数,可省略。 Output:参数是输出参数。 InputOutput:参数既能输入,也能输出。 ReturnValue:参数表示存储过程的返回值。,9.7 存储过程,3利用SqlDataAdapter或者SqlCommand调用存储过程在程序中利用SqlDataAdapter或者SqlCommand调用存储过程时,和定义存储过程中参数的定义一样,程序中也必须指明参数名、参数类型和参数方向。如果参数方向是输入参数,可以省略参数方向,其他情况均不能省略
36、。参数名不区分大小写,参数类型用SqlDbType枚举表示。 4利用数据集设计器调用存储过程将存储过程变为强类型的对象,这样编译器就可以在编译期间检查所有可能出现的错误。具体实现办法是,将存储过程从【服务器资源管理器】中直接拖放到数据集设计器中,让系统自动生成对应的组件,并自动生成对应的调用方法。,9.7 存储过程,【例9-14】演示存储过程的用法。设计界面:,9.8 语言集成查询(LINQ),9.8.1 LINQ简介LINQ是一组技术的统称。其主要思想是,它将各种查询功能直接集成到C#语言中,即用C#语法编写查询语句,而不是用针对特定数据库的SQL语法。 学习LINQ的关键主要有两点: 查询
37、表达式,用C# 3.0开始提供的语法编写; 对象关系设计器(O/R设计器),其形式有些类似于数据集设计器。 所有LINQ查询操作都由以下三部分组成: (1)获取数据源。 (2)定义查询表达式,并将查询表达式保存在某个查询变量中。 (3)利用查询变量执行查询。,9.8.1 LINQ简介,显示查询结果的办法主要有: (1)调用查询变量的属性或方法获取进一步的结果。 (2)在foreach语句中,通过遍历查询变量得到所有查询结果。 (3)用数据绑定显示查询结果,即将BindingSource绑定到查询变量,再将控件绑定到BindingSource,然后在窗体上将结果显示出来。,9.8.1 LINQ简
38、介,1查询数组 /创建数据源 int scores = new int 97, 92, 81, 60 ; /定义查询表达式 var query =from score in scoreswhere score 80select score; /执行查询 Console.WriteLine(“显示查询结果:“); foreach (int i in query) Console.Write(i + “, “); ,9.8.1 LINQ简介,2查询数据库 /前提:(1)在项目中新建一个名为MyDatabaseClasses.dbml的“LINQ to SQL类“文件 / (2)双击MyDataba
39、seClasses.dbml打开O/R设计器 / (3)从服务器资源管理器中将MyTable1拖到O/R设计器中 MyDatabaseClassesDataContext context=new MyDatabaseClassesDataContext( ); /定义查询表达式 var query =from table in context.MyTable1select table; /执行查询 Console.WriteLine(“记录数:0“, query.Count( ); foreach (var t in query) Console.WriteLine(“0,1“, t.编码,
40、t.名称); ,9.8.1 LINQ简介,3. 查询DataSet MyDatabaseDataSet dataset = new MyDatabaseDataSet( ); MyDatabaseDataSetTableAdapters.MyTable1TableAdapter adapter =new MyDatabaseDataSetTableAdapters.MyTable1TableAdapter( ); adapter.Fill(dataset.MyTable1); /定义查询表达式 var query =from table in dataset.MyTable1select ta
41、ble; /执行查询 foreach (var t in query) Console.WriteLine(“0,1“, t.编码, t.名称); ,9.8.2查询表达式,LINQ查询表达式由一组类似于SQL的声明性语法编写的子句组成。每个子句包含一个或多个表达式,而且表达式又可以包含子表达式。 LINQ查询表达式必须以from子句开头,并且必须以select或group子句结尾。在第一个from子句和最后一个select或group子句之间,查询表达式可以包含一个或多个where、orderby、join、let甚至附加的from子句。还可以使用into关键字将join或group子句的结果
42、作为附加查询子句的源数据。,9.8.2查询表达式,LINQ表达式的构成: 1from子句 from子句用于指定数据源和范围变量。 例如查询本章开头列出的表MyTable1: var query =from table1 in context.MyTable1select table1;,9.8.2 查询表达式,2where子句 where子句用于指定筛选条件,即只返回筛选表达式结果为true的元素。筛选表达式也是用C#语法来构造,例如: var query1 =from table1 in context.MyTable1where table1.编码 = “01“ ,9.8.2查询表达式,3
43、orderby子句 orderby子句用于对返回的结果进行排序,ascending关键字表示升序,descending关键字表示降序。例如: var query2 =from table2 in context.MyTable2where table2.性别 = 男 ,9.8.2 查询表达式,4group子句 group子句用于按指定的键分组,group后面可以用by指定分组的键。 例如: MyDatabaseClassesDataContext context = new MyDatabaseClassesDataContext( ); var query2 =from table2 in
44、context.MyTable2orderby table2.学号 ascending, table2.成绩 descendingwhere table2.性别 = 男 ,9.8.2查询表达式,5select子句 select子句用于生成查询结果并指定每个返回的元素的“形状”或类型。 除了前面所举的select子句的用法外,还可以用select子句让范围变量只包含成员的子集,例如查询结果只包含数据表中的一部分字段等。当select子句生成除源元素副本以外的内容时,该操作称为“投影”。,9.8.2 查询表达式,MyDatabaseClassesDataContext context = new
45、MyDatabaseClassesDataContext( ); var query2 =from table2 in context.MyTable2select table2.成绩; Console.WriteLine(“平均值:0,最大值:1“, query2.Average( ), query2.Max( ); var query3 =from table2 in context.MyTable2select new StudentName = table2.姓名, Grade = table2.成绩 ;,9.8.2 查询表达式,6join子句join子句用于将来自不同源序列并且在对象
46、模型中没有直接关系的元素相关联。每个join子句只接受两个源序列,如果有多个源,可以用多个join子句。,9.8.2 查询表达式,三种最常见的联接类型:内部联接、分组联接和左外部联接。 (1)内部联接内部联接产生一个结果集,对于该结果集内第一个集合中的每个元素,只要在第二个集合中存在一个匹配元素,该元素就会出现一次。如果第一个集合中的某个元素没有匹配元素,则它不会出现在结果集内。join子句所实现的内部联接就是关系数据库所描述的内部联接。,内部连接举例,var myQuery1 =from table2 in context.MyTable2join table3 in context.MyT
47、able3 on table2.学号 equals table3.学号select newStudentName = table2.姓名,ReleationName = table3.成员姓名,Releation = table3.与本人关系;,9.8.2 查询表达式,(2)分组联接 分组联接会产生一个分层的结果序列,该序列将左侧源序列中的元素与右侧源序列中的一个或多个匹配元素相关联。 例如: var myQuery1 =from table2 in context.MyTable2join table3 in context.MyTable3 on table2.学号 equals tabl
48、e3.学号 into relationselect newStudentName = table2.姓名,Releation = relation;,9.8.2 查询表达式,(3)左外部联接 左外部联接是这样一个联接:在其中返回第一个集合的每个元素,而无论该元素在第二个集合中是否具有相关元素。可以使用 LINQ,通过对分组联接的结果调用 DefaultIfEmpty 来执行左外部联接。 在左外部联接中,返回的是左侧源序列中的所有元素,即使它们在右侧序列中没有匹配的元素也是如此。,左外部连接举例,var myQuery1 =from table2 in context.MyTable2join
49、table3 in context.MyTable3 on table2.学号 equals table3.学号 into relationfrom item in relation.DefaultIfEmpty( )select newStudentName = table2.姓名,ReleationName = (item = null ? “-“ : item.成员姓名),Releation = (item = null ? “-“ : item.与本人关系);,9.8.3 对象关系设计器(O/R设计器),O/R设计器提供了一个可视化的图形设计界面,用于创建基于数据库中对象的LINQ to SQL实体类和关联(关系)。 O/R设计器用于在应用程序中创建映射到数据库中对象的对象模型。它还生成一个强类型DataContext,用于在实体类与数据库之间发送和接收数据。O/R设计器还提供了相关功能,用于将存储过程和函数映射到DataContext方法以便返回数据和填充实体类。最后,O/R设计器提供了设计实体类之间的继承关系的能力。,