书城计算机网络综合应用软件设计
19118400000026

第26章 软件构造(5)

6.4.1ADO.NET的定义

ADO.NET是托管应用程序所使用的数据库语言。它是.NET框架类库的System.Data命名空间和它的子空间提供的一组类。前面提到编程实际上就是管理和操作数据,而ADO.NET就是为管理和操作数据而生的。接下来就一起来探讨如何使用ADO.NET。

6.4.2使用ADO.NET

ADO.NET是.NET框架类库System.Data命名空间中的一组类。它包括了Connection对象、Command对象、DataAdapter对象、DataReader对象、DataSet对象及其他一些辅助对象。

首先先来看一下主要对象有些什么功能和作用。

Connection对象:建立与特定数据源的连接。

Command对象:对数据源执行命令。

DataReader对象:从数据源中读取只能单向前进且只读的数据流。

DataSet对象:DataSet是ADO.NET结构的主要组件,它是从数据源中检索到的数据在内存中的缓存。Data Set由一组Data Table对象组成,使用者可使这些对象与Data Relation对象互相关联。DataTable和Data Relation会在下文中有所介绍。

Data Adapter对象用数据源填充Data Set并解析更新。当然,还有一些很常用的对象,如Parameters对象和Command Builder对象。

Parameters对象定义命令和存储过程的输入、输出和返回值参数。而Command Builder对象将自动生成Data Adapter的命令属性或将从存储过程导出参数信息并填充Command对象的Parameters集合。这些对象究竟如何工作会在下面的文字中叙述。

若要在数据库中执行操作,应执行SQL语句或存储过程(它包括SQL语句)。可以使用SQL语句或存储过程读写行并执行聚合函数,例如添加或求平均值;还可使用SQL语句或存储过程创建或修改表或列、执行事务等。

在ADO.NET中,使用数据命令打包SQL语句或存储过程。例如,如果想要从数据库读取一组行,则创建一个数据命令并用SQLSelect语句的文本或获取记录的存储过程的名称配置它。所有使用ADO.NET与数据库进行交互,不管是显式的还是隐式的,都会牵扯到连接和命令对象。连接对象代表和数据库的物理连接;命令对象代表对数据库执行的命令操作。

这里给出了在ADO.NET中执行数据库命令的规范操作模式,规范操作模式如下。

①创建一个封装连接字符串的连接对象。

②调用连接对象的Open方法打开连接。

③创建一个封装SQL命令和连接的命令对象。

④调用命令对象的方法来执行该命令。

⑤调用连接对象的Close方法关闭连接。

下面提出几个能帮助大家解决数据库交互的操作:

1.如何设置数据库连接

在操作数据库之前,必须打开一个指向它的连接,由SqlConnection类代表了指向SQL Server数据库的连接。在Sql Connection类中有一个属性Connection String,存储了连接字符串。下面的语句创建了一个Sql Connection对象,并用一个连接字符串初始化。

Dim My Connection As New SqlConnection

My Connection.ConnectionString=”server=( localhost);database=ComponentSystem;Trusted_Connection=yes”)

只是创建一个Connection对象和提供一个连接字符串并没有打开一个指向数据库的物理连接,调用对象的Open方法才可能做到这一点。当然,在调用完数据库后别忘了用close方法关闭数据库。如果不能建立一个指向数据库的连接,SqlConnection.Open就会引发一个SqlException异常。

Try

My Connection.Open()

//TODO使用此连接

catch(ex as Sql Exception)

finally

My Connection.Close()

End Try

2.如何插入数据

一个打开的指向数据库的连接如果不用来执行命令就失去了意义,下面就来说一下命令类SqlCommand。SqlCommand实现了一些方法,可以调用这些方法来执行命令,如果是查询命令,会得到一个封装结果的DataReader对象。调用的方法和返回的结果取决于所要执行的命令。举例来说明:

Dim My Command As SqlCommand

My Command=New Sql Command(”Insert into tb_ClassBase(ClassId,ClassBaseID)values(+ClassID+,+lblBaseID.Text+)”,My Connection)

My Command.Execute NonQuery

当然还可以用命令对象的Command Timeout属性来指定命令执行的超时时间。

My Command.Command Timeout=10//保持连接10秒

Execute Non Query方法用来执行Insert、Update、Delete和其他没有返回值的SQL命令,它返回被命令影响的行数。ExecuteScalar方法执行一个SQL命令并返回结果集的第一列的第一行,它一般都用来执行SQL的COUNT、AVG、MIN、MAX和SUM函数,这些函数都是返回单行单列的结果集。

3.如何删除数据

同理定义一个命令对象SqlCommand。举例来说明:

Dim My Command As SqlCommand

My Command=New SqlCommand(”Delete from tb_Author where tb_Author=12”,_My Connection)

My Command.Execute NonQuery

4.如何更新数据

也同样是定义一个命令对象Sql Command。举例来说明:

Dim My Command As SqlCommand

My Command=New Sql Command(”update tb_componentbasicinformation set componentintroduction="”+txtcompintro.Text+”",componentcategoryid="”+category+”",toolid="”+tool+”",producttypeid="”+ product+”",componentfunctionid="”+funct+”",functionintroduction="”+txtfuncintro.Text+”"where componentid="”+lblcompid.Text+”"”,MyConnection)

My Command.Execute Non Query

5.如何查询数据

用来压轴的方法是Execute Reader,不为别的,因为它的使用频率最高。它能很快地对数据库进行查询并得到结果。ExecuteReader返回一个Data Reader对象,它可以作为一些数据类控件的数据源。一个查询操作可能产生几百万条记录,但是可以使用DataReader只读取其中的10条,这样只有部分结果集被返回,提高了性能。

下面是一个把从数据库中查询出来的数据作为一个下拉框控件的数据源的例子。先定义了一个名为sql的SQL查询字符串,然后建立一个Sql Command命令对象,并把刚才定义的sql作为参数传入Sql Command对象。接下来就是执行Execute Reader方法,得到一个DataReader对象。

sql=”Select producttypename From tb_producttype”

cmd=New SqlCommand(sql,conn)

rd=cmd.ExecuteReader

ddlprodtype.Items.Clear()

Do While rd.Read

ddlprodtype.Items.Add(rd(”producttypename”))

Loop

rd.Close()

ADO.NET的DataReader对数据库查询结果的基于流的访问,在只读记录集中只能以向前方式移动。用户不能退回去重读前一条记录,也不能改变查询结果并把它们写回数据库。于是,ADO.NET提供了基于集的访问。基于集的访问把整个查询结果记录在内存的缓存中,我们可以从任意方向访问并随意作出修改。

基于集的访问类是DataSet,它相当于内存中的数据库。而实际的数据存储在DataTable里,它是内存中的数据表。相对应的还有Data Row和Data Column。

DataSet通常是通过数据库查询或者XML文档来初始化的。DataSet不与数据库直接交互,而是由DataAdapter完成这项工作。

DataAdapter最重要的方法是Fill和Update。前者查询数据库并对结果初始化Dataset,后者把更改写回到数据库。

先给出一个例子:

Dim MyConnection As Sql Connection

Dim MyCommand As Sql DataAdapter

MyConnection=New Sql Connection(”server=( localhost);atabase=Component System;Trusted_Connection=yes”)

MyCommand=New Sql DataAdapter(”select AuthorID,AuthorName from tb_Author”,MyConnection)

Dim ds As DataSet

ds=New DataSet()

MyCommand.Fill(ds,”tb_Author”)

Mydatagrid.DataSource=ds.Tables(”tb_Author”).DefaultView

Mydatagrid.DataBind()

这段代码完成了很多工作。传递给DataAdapter的构造函数的查询字符串对指定的数据库执行查询;在Dataset中创建一个名为tb_Author的表;用数据库中的tb_Author表的架构初始化Data Table;检索由查询产生的所有记录,并把它们写入Data Table中;关闭指向数据库的连接。

在DataTable中执行插入、更新和删除操作并不会自动写回数据库。如果想把更改写回数据库必须手动完成。

Dim myConn As New SqlConnection(myConnection)

Dim myDataAdapter As New SqlDataAdapter()

myDataAdapter.SelectCommand=New SqlCommand(mySelectQuery,myConn)

Dim custCB As SqlCommandBuilder=New SqlCommandBuilder(myDataAdapter)

myConn.Open()

Dim custDS As DataSet=New DataSet

myDataAdapter.Fill(custDS)

myDataAdapter.Update(custDS)

myConn.Close()

CreateCmdsAndUpdate=custDS

至于Update怎样更新数据库的,在这里就不单独叙述了。在这里要提醒一点,在用SqlDataAdapter进行大量数据库的更新操作时,如果想提高性能,应该将数据库的更新操作编写在存储过程中,将这些存储过程包装在SqlCommand对象里,然后把这些对象赋值给InsertCommand、UpdateCommand或DeleteCommand属性。ADO.NET也支持视图概念。用DataView表示。它支持排序和筛选,可以用DataView的sort属性或rowFilter属性。那么有人也许要问,什么时候使用DataReader,而什么时候又该用DataSet呢?

在以下场合下考虑使用DataReader。

①当应用程序要求优化只读以及前向数据访问(如绑定Repeater控件)时,DataReader是一个更好的选择。当数据从DataReader“卸下”来时,就关闭连接,这对提供程序的性能有帮助。