第10章 使用ADO进行数据库访问_第1页
第10章 使用ADO进行数据库访问_第2页
第10章 使用ADO进行数据库访问_第3页
第10章 使用ADO进行数据库访问_第4页
第10章 使用ADO进行数据库访问_第5页
已阅读5页,还剩227页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第10章使用ADO.NET进行数据库访问10.1数据库概述10.2ADO.NET的基本组件10.3使用ADO.NET10.4综合案例:图书管理系统——使用DataGrid显示和操作数据 本章小结练习与作业上机部分(十)  学习目标●解释ADO.NET●掌握ADO.NET基本组件的使用●掌握基本数据库编程的步骤和方法10.1数 据 库 概 述数据库,顾名思义,就是存放数据的地方。在计算机中,数据库是数据和数据库对象的集合。数据库对象主要包括表、视图、存储过程、触发器等等,要管理数据库必须使用相应的管理系统。数据库管理系统(DBMS)就是一套计算机应用软件系统,主要作用是建立用户与数据库之间的信息处理通道,让用户能通过DBMS来存取和操作数据库中的数据,这些数据包括建立数据库、建立表格、添加、更新和删除数据以及查询数据等。目前通用的数据库管理系统主要有Access、SQLServer、Oracle、MySQL等。在使用数据库之前必须要理解一些基本的概念。

1.关系模型

关系模型把世界看做是实体(Entity)和联系(Relationship)构成的。所谓实体就是指现实世界中具有自身独有的特征或属性并与其他实体保持联系的对象。在关系模型中实体以表的形式来表现,表的每一行描述实体的一个实例,表的每一列描述实体的一个特征或属性。所谓联系就是指实体之间的关系或对应关系。联系可分为三种:一对一的联系。如:一个学生只有一个学号,姓名→学号为一对一的联系。一对多的联系。如:相同班级的学生有很多个,班级→学号为一对多的联系。多对一的联系。如:很多学生有同一个班级,学号→班级为多对一的联系。通过联系就可以用一个实体的信息来查找另一个实体的信息。在图10-1中,三张表组成了一个关系模型,每张表都是一个实体。从图10-1(c)中可看出,最终的结果依靠两张原始表的属性关系(如箭头所示)即学号的唯一标识得出。关系模型能够得到广泛使用的原因在于它的灵活性及操作的简单。如MicrosoftAccess数据库、SQLServer数据库都是基于这种模型。图10-1关系模型

2.关系数据库对象

1)表表是数据库的对象,表包含数据库的数据。一个数据库由一个或多个表组成,每个表存储一些相关的数据。数据库中的表与表之间有时可能存在着关联。表是一个分别排成行跟列的相关记录的集合,类似于二维数组或Excel中的电子表格。数据就是以行和列的形式进行存储,每个列表头就是一个字段,每一行存储实际的数据。在设计表时我们可以根据功能为表创建各种列,如针对图10-1所示的学生信息表,采用Access数据库,设计了三列,分别为学号、姓名和所属班级。请看图10-2所示学生信息表的具体结构。图10-2学生信息表结构

2)记录和字段记录是表示数据的集合。记录在逻辑上相当于表的行。例如,学生信息表的一条记录可能就包含某个学生的信息。记录是由多个字段组成的。记录中的每个字段都包含了关于该记录的单条信息。例如,学生信息表记录有学号、姓名和所属班级等字段。图10-3对学生信息表添加了一些记录。图10-3学生信息表

3)主键主键唯一标识了表的每一行。主键可以是一个字段,也可以是几个字段的组合。对表中的每一行(记录)来说,主键的值都是惟一的。例如,“学号”字段是“学生信息表”的主键,因为任何两个学生的学号都不相同。在Access中,可以通过鼠标操作的方式为表添加一个主键,如图10-4中学号上有个标识。图10-4具有主键的学生信息表

4)外键外键是由一个或者多个字段组成的,而这些字段又是其他表的主键(列)。外键描述了表与表之间的关联方式。

5)关系关系是建立在两个表的公共字段(列)之间的一种关联。关联可以是一对一、一对多或者多对多。关系使查询结果中可以包括来自多个表的数据。例如,图10-5所示的班级信息表和学生信息表之间的一对多关系将允许查询返回相关专业的所有学生。图10-5表的关系

3.SQL语言

前面简单地介绍了一下数据库的模型及一些基本的术语,学到这里不知读者有没有想过,怎么样才能在一个程序中把数据放进数据库呢?如何得到数据库的数据呢?如何去更新、修改数据库里面的数据呢?……

解决这些问题其实很简单,就是利用SQL语言。SQL(StructuredQueryLanguage)全称是“结构化查询语言”,是数据库中使用的标准数据查询语言。早前美国ANSI对SQL进行规范后作为关系数据库管理系统的标准语言,后来得到国际标准化组织(ISO)的支持已成为国际标准。SQL是一种高级的非过程化语言,从名称上看,SQL适合于编写查询语句,可实际上它实现的功能远远不止于查询,如创建、删除、修改、更新等一些对数据库的操作都能得心应手。接下来针对项目中的数据表来编写SQL语句来实现对表数据的查找、插入、更新、删除等操作。1) Createtable语句Createtable语句用于在数据库中建立一张新表,包括表的结构。在Access数据库中,读者可以使用图形化界面直接创建及修改。也可以通过SQL语句灵活实现。这里只要了解利用语句是如何编写就行了。请看下面对Createtable语句的定义:Createtable表名(列名1类型,列名2类型,…,其他参数)

在数据库中需要创建一个名称为“学生成绩表”的表格:Createtable学生成绩表(学号intPRIMARYKEY,姓名char(10),高等数学integer,数据结构integer,大学语文integer,体育integer);2) Altertable语句Altertable语句用于修改表的结构,语句定义如下:Altertable表名ALTERCOLUMN列名类型|ADD列名类型|DROPCOLUMN列名前面创建了一张学生成绩表,现在用Altertable语句来修改学生成绩表的结构:Altertable学生成绩表ADD性别char(2);Altertable学生成绩表ALTERCOLUMN姓名char(8);

说明:在上面的两个范例中,利用Altertable语句向学生成绩表中添加一个名为“性别”的列,并把学生成绩表名为“姓名”的列的数据类型大小改为8。3) INSERTINTO语句前面利用Createtable语句为学生信息管理项目创建了表的结构,现在还需要往表里存放数据、读取数据及修改数据等操作。INSERTINTO命令语句就是用来向表中的列插入值。INSERTINTO语句定义如下:INSERTINTO表名(列名1,列名2,…)VALUES(常量1,常量2,…)其中(列名1,列名2,…)可省略。例句:INSERTINTO学生成绩表VALUES(0001,'李明',88.5,69,75,90);

学号姓名高等数学……

说明:在上述例句中,利用INSERTINTO语句向学生成绩表的各列都插了值,现表中已有一行值。注:括号后面的值应该跟所定义表的结构的顺序一致。如果表的结构中有定义字符的数据类型,应使用单引号。4) UPDATE语句利用UPDATE命令语句可用于更新表中的数据。定义如下:

UPDATE表名SET字段=值,字段=值,…WHERE条件语句例句1:UPDATE学生成绩表SET体育=85WHERE学号=0001;例句2:UPDATE学生成绩表SET体育=85;

说明:在上面的两个例句中,利用UPDATE语句对学生成绩表进行更新。例句1把学生成绩表的学号为0001的学生的体育成绩更改为85分。例句2把学生成绩表的每位学生的体育成绩都更改为85分。不使用WHERE子句UPDATE命令将更新表中的所有行。5) DELETE语句利用Delete语句可用于删除表的记录。定义如下:

DELETEFROM表名WHERE条件语句请看范例:DELETEFROM学生成绩表WHERE学号=03002;解释:利用DELETE语句把学生成绩表的学号为03002的学生的记录删除。6) SELECT语句对数据库的数据进行查询是SQL语言的核心部分,语句的一般格式为:SELECT目标列FROM表名WHERE条件语句GROUPBY列名1HAVING内部函数表达式ORDERBY列名2ASC/DESC例句(1):SELECT学号FROM学生成绩表;说明:使用SELECT语句查找学生成绩表的所有学号的值。例句(2):SELECT学号,姓名From学生成绩表;说明:使用SELECT语句查找学生成绩表的所有学号、姓名的值。例句(3):SELECT*FROM学生成绩表;说明:使用SELECT语句查找学生成绩表的所有记录,即学生成绩表中的所有行。“*”代表所有列。接下来用限定词、通配符、函数及操作数等来对SELECT语句进一步扩充。●通配符与多重条件查询通配符使用LIKE或NOTLIKE操作数进行模糊条件查询,以判断列值是否与指定的字符串格式相匹配。常用通配符如表10-1所示。表10-1常用通配符例句(4):SELECT*FROM学生成绩表WHERE姓名LILE'J%';说明:使用SELECT语句查询学生成绩表所有列值首字符为“J”的值。上面的插入、更新、删除、查找命令为SQL语句最为基础也是最常用的命令,事实上在一般项目中用得多的就是SELECT语句命令了,而其他的的插入、更新等命令则不必编写,因为可以借助ADO.NET技术的CommandBuilder对象自动生成。如果读者有兴趣的话可以再进一步学习有关SQL语句命令的扩充。7) DROP、DELETE、TRUNCATETABLF语句的区别DROP、DELETE、TRUNCATETABLE语句都为删除命令语句,但它们之间的使用是有区别的。DROP语句用于删除整个表格,即删除表的数据跟表结构;DELETE语句用于有选择地删除表中的行值;TRUNCATETABLE语句用于删除整个表所有行的值,但不删除表结构。语法定义如下:DROPTABLE表名;DELETEFROM表名WHERE条件语句;TRUNCATEtable表名;

下面通过一些SQL语句示例实现对表中数据进行操作。先创建一个名STUDENT的表,并向表插入三行值(利用CREATETABLE、INSERTINTO语句)。CreatetableSTUDENT(学号int,姓名char(8),年龄int);INSERTINTOSTUDENTVALUES(03001,'张三',20);INSERTINTOSTUDENTVALUES(03002,'李四',21);INSERTINTOSTUDENTVALUES(03003,'王五',23);例句(1):DELETEFROMSTUDENTWHERE学号=03002;说明:删除STUDENT表中学号为03002学生的记录。例句(2):TRUNCATETABLESTUDENT;说明:删除STUENDT表的所有行,即表中的所有学生信息全部删除。例句(3):DROPTABLESTUDENT;说明:删除STUDENT表。注意:DROPTABLEI不能删除有外键约束引用的表,必须先将外键约束删除。TRUNCATETABLE同样不能用于有外键约束引用的表,在这种情况下,就要用到不带WHERE子句的DELETE语句了。

8)使用AND、OR、NOT关键字进行多重条件查询例句:

SELECT姓名FROMSTUDENTWHERE学号=03003AND年龄=22; 说明:查询STUDENT表中列为姓名的学号为03003且年龄为22的值。注意:在运算过程中NOT优先级最高,次之AND最后为OR,但可通过加括号来改变。

9)使用ALL、DISTINCT、TCOP限定词TOP关键字用来限制显示查询返回得到的行数。例句(1):SELECTTOP2*FROMSTUDENT;

说明:查询STUDENT表的所有行且只显示前两行。ALL关键字用来显示查询返回得到的所有行(包括重复的行)。例句(2):SELECTALL学号FROMSTUDENT;说明:查询STUDENT表的学号字段所有行的值。DISTINCT关键字用来删除查询得到的重复值的行。例句(3):SELECTDISTINCT学号FROMSTUDENT;说明:查询STUDENTG表的学号字段不重复值的所有行的值。

10)使用[NOT]Between…AND…与IN关键字Between…AND…用于查找字段值在或者不在指定范围内的值。例句(1):SELECT*FROMSTUDENTWHERE年龄Between20AND23;说明:查询在STUDENT表中年龄介于20~23之间的所有行。例句(2):SELECT*FROMSTUDENTWHERE年龄NOTBetween20AND23;说明:查询在STUDENT表中年龄不介于20~23之间的所有行。IN关键字用来查找字段值属于在指定集合的范围内的值。例句(3):SELECT*FROMSTUDENTWHERE学号in('03001','03003');说明:查询在STUDENT表中学号为03001跟03003的所有行。

11)使用集合函数

集合函数用于统计个数及计算数值,功能如表10-2所示。表10-2常用集合函数表说明:ALL与DISTINCT是可选项,ALL计算时忽略重复,DISTINCT则不重复。COUNT(*)会返回所有行包括值为空(NULL)的记录行数,COUNT(field)则不返回值为空的记录行数。例句:SELECTCOUNT(姓名)FROM学生成绩表WHERE高等数学>80;

说明:查询学生成绩表中高等数学80分以上的学生的姓名。

12)使用ORDERBY、GROUPBY、HAVING子句OREDERBY子句用于对查询所得行进行排序,关键字ASC为升序,DESC为降序,默认则为升序排序;GROUPBY子句用于对查询所得行按某一列或多列值进行分组显示,值相等的则为同一组;HAVING子句则用于在使用GROUPBY子句进行分组后对行进行判断筛选。例句(1):SELECT*FROMSTUDENTORDERBY年龄DESC;说明:查询STUDENT表的所有记录并以年龄字段显示为降序排序。例句(2):SELECT姓名FROM学生成绩表GROUPBY学号HAVING高等数学>60;说明:查询STUDENT表中高等数学分数60分以上的学生的姓名,并以学号字段进行分组显示。

注意:HAVING子句应始终在GROUPBY子句之后使用。上面所讲的SQL语法只是一些比较简单、常用的语句。如果读者想再对SQL语言进一步深入学习、探索的话,应该看一些其他关于SQL方面的书籍,如SQLSERVER等。10.2ADO.NET的基本组件无论需要怎样使用数据,都应该理解ADO.NET中数据方法的一些基本概念。你也许永远不需要知道数据处理的一些细节,但是理解ADO.NET中的数据结构和主要数据组件,以及理解各部分如何组合到一起,都会对你有所帮助。本节并不讲述详尽的细节,而是介绍ADO.NET中与数据集成相关的概念。1.定义ADO.NET是.NETFramework架构中一组用于数据操作的类。它提供了为非连接环境设计的系统、高级XML支持的编程模型和在Microsoft.NET框架内用于数据访问的类、接口、结构和枚举类型。ADO.NET组件主要分为两大类:(1)数据存取:DataSet类,独立于不同数据源的数据存取服务组件。(2)数据操作:.NETFrameworkDataProvider和NETFramework的数据提供者,包含有四个核心组件:Connection对象、Command对象、DataReader对象和DataAdapter对象。利用微软官方发布的ADO.NET架构图(如图10-6),可以让我们更清楚地了解上述两大类组件之间的关系。图10-6ADO.NET架构图2.ADO.NET对象概述ADO.NET中Connection对象建立到数据源的连接。它有ConnectionString属性、Open和Close方法以及使用BeginTransaction方法开始事务处理的能力。Command对象允许你查询数据库、向它发送命令或者调用它的存储过程。可以使用该对象的某个Executexxx方法来执行这些操作。例如,使用ExecuteNonQuery方法向数据库发送操作查询(比如INSERT或DELETESQL语句),并使用ExecuteReader方法执行会返回结果集的SELECT查询。其他属性允许你设置命令超时或为调用存储过程设置参数。你必须手动地把Command对象和先前已经连接到数据源的Connection对象相关联。DataReader对象是Command对象的ExecuteReader方法返回的对象,它代表只向前的、只读的结果集。每次调用DataReader的Read方法时都会产生一行新的可用结果,然后,就可以使用GetValue方法或者某个强制类型的Getxxx方法(比如GetString或GetFloat)查询每个单独的字段。记住,不能使用DataReader对象更新数据库。DataAdapte对象起着Connection对象和DataSet对象之间的桥梁作用。其Fill方法将数据从数据库移到客户端的DataSet对象,而其Update方法则按相反方向移动数据,它使用由应用程序在DataSet中添加、更改或删除的行对数据库进行更新。DataSet对象是ADO.NET非连接架构下的主要对象。它在使用时就像驻留在客户端计算机上的一个小型关系数据库,但又与任何具体的数据库完全无关。它包含一个DataTable对象的集合,其中每个DataTable对象都包含一个不同的结果集(通常情况下,它是对不同数据库表的查询结果)。DataTable对象包含一个DataRow对象的集合,而每个DataRow对象则包含了结果集里不同行中的数据。DataSet还包含一个DataRelation对象的集合,其中每一项都对应一个不同DataTable对象之间的关系,这很像关系数据库中表与表之间的关系。这些关系允许你使用简单而又很有效的语法编写代码,从而实现同一DataSet中表与表之间的导航。.NET框架包括许多 .NETDataProvider,例如SQL

Server.NETDataProvider,OLEDB.NETDataProviderforSQL和OLEDBProviderforMicrosoftJet等。你也可以为任意数据源编写自定义的.NETDataProvider。3.ADO.NET组件的命名空间结构ADO.NET中常用的NETFramework数据提供组件有两种,分别是SQLServer数据提供组件和OLEDB数据提供组件。前者支持SQLServer7.0或更高版本,直接与SQLServer底层API沟通,性能较高。它属于System.Data.SqlClient命名空间。OLEDB数据提供组件用于访问如Access、Oracle等数据源。当然OLEDB组件也可以用于访问SQLServer数据源,但由于有中间层的加入,性能不是很好。该组件属于System.Data.OleDb命名空间。上面两种数据提供组件,都实现了Connection对象、Command对象、DataReader对象和DataAdapter对象的模型,如表10-3所示。此外,我们还将使用到System.Data命名空间,它也是.NETFramework用来存取数据的主要组件。表10-4介绍了System.Data的几个常见的子类。各个子类的关系如图10-7所示。表10-3两种数据提供组件中的对象表10-4System.Data的几个常见的子类图10-7System.Data中各个子类的关系使用VisualStudio2005创建程序时,系统将默认应用System.Data.dll组件。因此,不需要再添加对System.Data的引用,直接在程序中使用using把命名空间导入即可。如果要引用该组件,请在项目的引用上单击,添加相应的组件,如图10-8所示。

注意:组件,也叫程序集,是命名空间的物理表示。如果要使用usingSystem.Data;语句,必须先将System.dll组件添加进来。直接在项目中输入using语句是无效的。图10-8添加程序集引用10.3使用ADO.NET开发应用程序时,可能需要通过不同的方式使用数据,有时只希望数据显示在窗体上,而有时需要设计一种方法来与其他组织共享信息。使用数据时,可以使用各种对象来检索和修改数据库中的信息。一般来说,要在ADO.NET中使用数据库,需要执行下列步骤:(1)连接到数据库。(2)请求特定的数据。确定想要检索的数据以及需要对它进行访问的方式是只读访问还是读/写访问。(3)检索并显示数据。(4)关闭连接(在某些应用程序中)。(5)修改检索得到的数据(如果有读/写访问权限)。(6)重新打开连接(在某些应用程序中)。(7)将对数据所做的所有更改都传回数据库。(8)关闭连接。在上述过程中,必须采用ADO.NET中用于连接数据源和使用数据的所有必要组件。在本节里,将学习这些组件对象的创建和设置,以及如何使用这些对象连接到数据库、检索数据、修改数据以及如何将更新后的数据传回数据库。10.3.1使用Connection对象无论是在连接模式还是非连接模式下工作,在使用数据源时,需要执行的第一步都是打开到数据源的连接。用ADO.NET术语,这就意味着创建一个到指定数据库的Connection对象。1.选择Connection对象可以使用Connection对象来连接特定的数据源。既可以使用SqlConnection连接到SQLServer数据库,也可以使用OleDbConnection连接到其他类型的数据源。这里要注意的是,SqlConnection和OleDbConnection位于不同的命名空间下,分别为System.Data.OleDb和System.Data.SqlClient,使用时请先将其导入。表10-5和表10-6分别说明了两种Connection对象的属性和方法。表10-5SqlConnection属性和方法表10-6OleDbConnection的属性和方法2.指定数据源在选择了连接对象类型之后,可以使用Connection对象ConnectionString属性来指定DataProvider、数据源和其他用于建立连接的信息。连接字符串的格式在SqlClient命名空间和OleDb命名空间之间稍有不同。3.设置ConnectionString属性ConnectionString是Connection对象的关键属性,它是一个字符串,用于定义正在连接的数据库的类型、位置以及其他属性,这些属性用分号分隔。通常情况下,该字符串包含如下信息:(1) Provider特性:它指定用于连接到数据的OLEDBProvider的名称。在书写时,所有合法的值包括SQLOLEDB(MicrosoftSQLServer的OLEDBProvider)、Microsoft.Jet.OLEDB.4.0(MicrosoftAccess的OLEDBProvider)和MSDAORA(Oracle的OLEDBProvider)。(2) DataSource特性:它指定数据库的位置,既可以是Access数据库的路径,也可以是SQLServer或Oracle数据库所在计算机的名称。(3) UserID和Password特性:它们指定用户名和该数据库的有效帐户密码。(4) InitialCatalog特性:当连接到SQLServer或Oracle数据源时,它指定数据库的名称。(5) IntegratedSecurity特性:SQLServer的整合安全性。若为True,则用Windows帐户进行验证;若为False,则需要在连接时指定用户名和密码。一旦正确设置了ConnectionString,就可以通过调用Open方法打开连接:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+ "DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection();cn.ConnectionString=constr;cn.Open(); //打开db1数据库通过将连接字符串传递给Connection对象的构造函数,可以使代码更为简洁:OleDbConnectioncn=newOleDbConnection(constr);cn.Open(); //更简洁的方式打开db1数据库以上描述同样可以用于SqlConnection对象,其中只有一个区别:不能包括连接字符串的Provider特性。实际上,在这种情况下根本就不需要该特性,因为使用SQLServer.NETDataProvider时,只能连接到SQLServer数据库。另一个要注意的地方是如果连接到本地计算机上的SQLServer,可以将DataSource特性指定为(local):stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);cn.Open();该连接字符串可以包括一些其他特性。例如,ConnectionTimeout特性用来设置连接尝试能够等待的时间(缺省值为15秒),如在这段时间内无法连接,将返回错误。打开连接之后,可以用ConnectionTimeout属性查询该超时时段长度://指定一个更长的连接到Pubs时的超时时段。stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs;ConnectionTimeout=30";SqlConnectioncn=newSqlConnection(constr);cn.Open();Debug.Write(cn.ConnectionTimeout); //在输出窗口显示30是否要在连接字符串中传递其他值,取决于连接所使用的特定OLEDBProvider。例如,Microsoft.Jet.OLEDB.4.0的Provider支持设置数据库密码,也支持包含有关组和用户信息的系统数据库。使用SQLServer.NETDataProvider,可以在连接字符串中指定其他两个属性:PacketSize和WorkstationID。前者用来设置网络数据包(该数据包用于与SQLServer通信)的大小;后者可以用于标识客户端。有时,PacketSize属性对于优化应用程序与SQLServer之间的数据流量很有用处。例如,如果处理大的BLOB字段(比如图像),那么可以设置一个较大的值;如果经常对服务器作小数据量的查询,那么可以设置一个较小的值。//优化对BLOB的连接。stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs;PacketSize=32767";SqlConnectioncn=newSqlConnection(constr);cn.Open();Debug.Write(cn.PacketSize); //在输出窗口显示327674.打开和关闭连接如前所述,Open方法和Close方法不带参数:OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//执行数据库操作cn.Close();● State属性和StateChange事件(1) State属性是一个按位编码的字段,指示数据库连接的当前状态。它可以是下列ConnectionState枚举值中一个或者多个值的组合:Closed、Connecting、Open、Executing、Fetching和Broken。通常情况下,需检查State属性以确保打开一个关闭着的连接或者关闭一个已打开的连接,如下列代码所示://如果连接已打开,关闭该连接if(cn.State==ConnectionState.Open) cn.Close();;需要注意的是,当连接不再需要时,应该及时把它关闭,以免占用过多的数据库连接资源。(2)StateChange事件是当State属性发生改变时触发的,经常用在“当数据库连接对象的连接状态发生改变时”,可以对连接对象进行及时处理。

【例10-1】使用控制台程序建立对SQLServer的连接。usingSystem;usingSystem.Data.SqlClient;usingSystem.Data;classTestConnection{staticvoidMain(){SqlConnectioncn=newSqlConnection();//创建一个连接对象try{stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=NorthWind";cn.ConnectionString=constr; //设置连接字符串cn.Open();Console.WriteLine("连接已打开");}catch(SqlExceptione){Console.WriteLine(e.Message);}finally{if(cn.State!=ConnectionState.Closed)//判断连接状态{cn.Close();Console.WriteLine("连接已关闭");}}}}程序的运行效果如图10-9所示。图10-9运行结果10.3.2使用Command对象在打开了连接之后,你可以决定是在连接环境还是非连接环境下工作。对前一种情况,通常可以创建一个Command对象,该对象包含一个选择查询(从数据库读取数据)或者一个操作查询(更新数据),然后执行Executexxx方法(确切的名称取决于查询的类型)。Command对象按数据库类型也分为两大类:SqlCommand用于执行SQLServer中的命令,OleDbCommand对象用于执行非SQLServer数据库中的命令。表10-7和表10-8分别说明了两种Command对象的属性和方法。表10-7SqlCommand的属性和方法表10-8OleDbCommand的属性的方法1.创建Command对象对象的关键属性是CommandText(执行操作查询或选择查询的SQL文本)和Connection(查询所基于的连接)。你可以逐个设置这些属性,如下列代码所示://创建和打开连接stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+"DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//设置执行字符串stringsqlstr="insertintoStudent(stuid,name)values(5,'mike')";OleDbCommandcmd=newOleDbCommand();cmd.Connection=cn;cmd.CommandText=sqlstr;//执行语句,返回被影响的行数intrecords=cmd.ExecuteNonQuery();Debug.Write(records); //输出1//关闭连接cn.Close();也可以将这两个值传递给Command对象的构造方法,这样代码更简洁:OleDbCommandcmd=newOleDbCommand(sqlstr,cn);2.发出数据库命令正如在前面的代码中所看到的,使用ExecuteNonQuery方法(它返回受到该语句影响的记录的数目),可以通过Command对象来执行插入、更新和删除操作:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+ "DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//设置执行字符串,删除一条记录stringsqlstr="deletefromStudentwherestuid=5";OleDbCommandcmd=newOleDbCommand(sqlstr,cn);intrecords=cmd.ExecuteNonQuery();Debug.Write(records); //输出1cn.Close();当然,从安全及排错的角度来说,应该将它(以及所有的数据库操作)放在try代码块中保护起来:try{ //运行查询;获取受影响记录的数目 intrecords=cmd.ExecuteNonQuery();}catch{ //在这里处理错误 ...}finally{ //总是关闭连接 cn.Close();}【例10-2】使用Windows程序操作SQLServer数据库,步骤如下:(1)首先创建一个WinForm程序,对窗体Form1的设计界面如图10-10所示。图10-10设计界面(2)导入所需的命名空间,然后在代码区定义成员变量及方法。SqlConnectioncn=newSqlConnection("DataSource=(local);UserID=sa;Password=41919;InitialCatalog=northwind");SqlCommandcmd=newSqlCommand();privateboolcheckSame(stringbh) //判断输入的客户号是否重复{cmd.Connection=cn;cmd.CommandText="selectcount(*)fromcustomerswherecustomerid='"+bh+"'";if(cmd.ExecuteScalar().ToString()=="0")returntrue;elsereturnfalse;}(3)在【添加记录】按钮的Click事件中添加如下代码:privatevoidbutton1_Click(objectsender,EventArgse){stringkhh,gsm,xm;khh=textBox1.Text;gsm=textBox2.Text;xm=textBox3.Text;try{if(cn.State==ConnectionState.Closed)cn.Open();if(checkSame(khh)==false{MessageBox.Show("存在相同的客户号,请重新输入!");textBox1.Focus();}else{cmd.CommandText="insertintocustomers(customerid,companyname,contactname)values('"+khh+"','"+gsm+"','"+xm+"')";cmd.Connection=cn;cmd.ExecuteNonQuery(); //执行添加操作MessageBox.Show("记录已成功添加!");}}catch(SqlExceptionex){MessageBox.Show(ex.Message);}finally{cn.Close();}}(4)保存并运行程序,结果如图10-11所示。图10-11运行结果10.3.3使用DataReader对象此对象用于从数据源中获取只读和只进数据。DataReader在任何时候都只在内存中保存一行数据,减少了内存开销,提高了性能。和Connection对象一样,DataReader对象也包含两种类型:SqlDataReader和OleDbDataReader。表10-9和表10-10分别说明了两种DataReader对象的属性和方法。使用DataReader对象也很简单:调用它的Read方法前进到数据集的下一行,并检查其返回值。如果返回值为false,则已经到了数据集的末端;如果返回值为true,则还有更多的记录。根据这个布尔函数,可以使用DataReader对象建立循环://创建和打开连接stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+ "DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//设置执行字符串stringsqlstr="selectstuidfromStudent";OleDbCommandcmd=newOleDbCommand(sqlstr,cn);OleDbDataReaderdr=cmd.ExecuteReader();while(dr.Read()) //循环读取DataReader中的每一条记录{Debug.WriteLine("stuid:"+dr.GetInt16(0));}//关闭连接cn.Close();表10-9SqlDataReader的属性和方法表10-10OleDbtaReader的属性和方法当不必再对行进行处理的时候,一定要关闭DataReader对象。这样可以释放客户端计算机和服务器上的资源,并使得该连接可以再度为其他命令所用。实际上,当连接上有激活的DataReader对象时,你就不能在该连接上发出任何其他命令。DataReader在使用一个连接时,在该连接上惟一可以执行的命令就是Close方法。可以通过连接的State属性检查它是否可用。DataReader对象没有这种属性,不过可以通过它的IsClosed属性来检查它是否已经关闭。【例10-3】使用Windows程序显示数据,步骤如下:(1)首先创建一个WinForm程序,窗体Form1的设计界面如图10-12所示。图10-12设计界面(2)添加成员变量,并在Form_Load事件中添加如下代码。SqlConnectioncn=newSqlConnection("DataSource=(local);UserID=sa;Password=41919;InitialCatalog=northwind"); //创建连接SqlCommandcmd=newSqlCommand(); //创建命令privatevoidForm1_Load(objectsender,EventArgse){try{cn.Open();cmd.CommandText="selectcustomeridfromcustomers";cmd.Connection=cn;

SqlDataReaderdr=cmd.ExecuteReader(); //执行记录查询while(dr.Read()) //循环读取记录{comboBox1.Items.Add(dr[0]); //装载记录值}}catch(SqlExceptionex){MessageBox.Show(ex.Message);}finally{cn.Close();}}(3)保存并运行程序,结果如图10-13所示。图10-13运行结果10.3.4使用DataAdapter对象使用Command对象执行查询操作后,在使用DataReader对象的Read方法就可以从数据库中检索出数据,但DataReader对象不能处理表和记录间的复杂关系。为此,ADO.NET引入了另一个核心的对象DataSet(数据集)。那么DataSet是如何从数据库中获得数据的呢?我们采用的是DataAdapter(数据适配器)对象来完成这个任务。数据适配器(DataAdapter)对象用来实现数据源和DataSet数据集之间的数据交换。在很多应用程序中,这意味着借助于DataAdapter从数据库将数据读入DataSet,然后将更改后的数据从DataSet传回数据库。DataAdapter可以在任何数据源和数据集之间移动数据。对每一种类型的NETFramework数据提供者来说,都有一个DataAdapter类。所以才会有OleDbDataAdapter和SqlDataAdapter类,并且它们都提供相同的属性和方法。将来要发布的所有 .NETDataProvider都将包含它们自己的DataAdapter,因为DataAdapter必须知道如何从特定的数据源读取数据以及更新该数据源。除了名称和少数其他细节(比如如何处理参数)之外,使用OleDbDataAdapter和SqlDataAdapter的方法是完全一样的。表10-11说明了SqlDataReader对象的属性和方法,OleDbDataAdapter对象的属性和方法与之类似。表10-11SqlDataAdapter的属性和方法1.创建DataAdapter在声明DataAdapter对象时,你可以向它传递作为参数的查询字符串和Connection对象来初始化该DataAdapter。DataAdapter会检查Connection对应的连接是否已打开,如果没有打开,就自动打开该连接并在方法调用结束时关闭该连接。这种做法适合于下面的情况:应用程序已经设置好Connection对象的属性并且打开连接只是为了填充数据集。下面的例子说明了如何创建一个SqlDataAdapter类的对象,并用该对象将Pubs数据库的Titles表中所有的数据存入DataSet数据集中。//创建和打开连接stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);//创建数据适配器对象SqlDataAdapterda=newSqlDataAdapter("select*fromTitles",cn);//装入数据集的代码DataSetds=newDataSet();da.Fill(ds,"Title");//绑定数据集到窗体控件的代码可以放在这里…下例说明了如何通过OleDbAdapter访问Access数据库db1的Student表:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+"DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);OleDbDataAdapterda=newOleDbDataAdapter("select*fromstudent",cn);//创建适配器对象DataSetds=newDataSet();da.Fill(ds,"Student"); //填充数据集2.DataAdapter对象的关键方法DataAdapter提供在数据集和数据源之间移动数据的特定方法。可以使用DataAdapter执行下列操作:(1)检索数据库中的行并将它们装入到数据集的相应数据表中。如要检索数据存储中的行并把它们装入数据集,请使用SqlDataAdapter或OleDbDataAdapter的Fill方法。调用该方法时,它会调用数据存储中的SQLSELECT语句。执行该方法将打开和关闭连接对象。(2)将对数据集表的更改写回相应的数据存储。如要将对数据集表的更改写到数据存储,请使用该适配器的Update方法。调用该方法时,根据受影响的记录状态是新建、更改或删除,它将执行相应的SQL的INSERT、UPDATE或DELETE语句。执行该方法将打开和关闭连接对象。下面的代码段演示了如何使用这两种方法。//创建和打开连接stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);//创建数据适配器对象SqlDataAdapterda=newSqlDataAdapter("select*fromTitles",cn);//装入数据集的代码DataSetds=newDataSet();da.Fill(ds,"Titles");//下面可添加代码以在本地使用DataSet操作数据…//将DataSet的更新传回数据源da.Update(ds.Tables["Titles"]);3.熟悉更新的概念通过使用DataAdapter的Update方法可以使用DataSet来更新数据库中的数据,该方法的参数有三种:(1) DataTable对象:该对象用作更新操作的数据源。(2)  DataSet加上DataTable的名称:是指明将特定表用作更新操作所用数据源的另一种方法(如果不指定表名,该命令会使用名为Table的DataTable)。(3)  DataRow对象数组:只有这个数组中的记录被用作更新操作的数据源。表中的行是按一定顺序发送到数据库的,当需要对记录更新的顺序进行进一步控制时,可以使用该数组。在所有情况下,Update方法都会返回已经成功更新的行的数目。用ADO.NET执行更新的关键在于DataAdapter对象的三个属性:InsertCommand,UpdateCommand和DeleteCommand。这三个属性连同SelectCommand就好象DataAdapter的四个帮手一样,各自执行特定的任务。以下是更新机制的工作方式。发出Update命令时,DataAdapter检查被指定为要进行更新操作的每一行的RowState属性。当该状态是Added时,DataAdapter就发出在InsertCommand属性中指定的SQL命令。如

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论