2.1 数据接口模块

在ASP.NET中,使用ADO.NET组件访问数据库,本节将介绍ADO.NET组件及其对象,包括如何使用Connection对象连接不同的数据库,如何使用Command对象操作数据库,如何使用DataReader对象和DataSet对象读取数据库中的数据。

2.1.1 ADO.NET概述

ADO.NET是基于.NET框架的用于数据访问的组件。ADO.NET是ADO技术的发展,在ADO.NET中,可以使用新的.NET Framework数据提供程序来访问数据源。这些数据提供程序包括:SQL Server .NET Framework数据提供程序、OLE DB .NET Framework数据提供程序、ODBC .NET Framework数据提供程序、Oracle .NET Framework数据提供程序等。这些数据提供程序可以满足各种开发要求,包括中间层业务对象(它们使用与关系数据库和其他存储区中的数据的活动连接)。ADO.NET是专为基于消息的Web应用程序而设计的,同时还能为其他应用程序结构提供较好的功能。

2.1.2 ADO.NET对象

为了实现数据访问和数据操作的分离,ADO.NET提供了两种组件:.NET Data Provider和DataSet。DataSet对象提供了一个与数据源无关的数据表示方式,.NET Data Provider含有4个对象:Connection、Command、DataReader和DataAdapter,如图2-1所示。Data Provider用于实现数据操作和对数据的快速访问。使用Data Provider对数据库操作后的结果可以被直接处理,也可以被放到DataSet对象中。

图2-1 ADO.NET组成结构

1. .NET Data Provider

.NET Framework提供了 4个内置的.NET Data Provider:.NET Data Provider for SQL Server、.NET Data Provider for OLE DB、.NET Data Provider for Oracle和.NET Data Provider for ODBC。每个.NET Data Provider都是在.NET Framework中各自的命名空间中维护的。其中,.NET Data Provider for SQL Server包含在System.Data.SqlClient命名空间中,用于连接Microsoft SQL Server7.0或者更高版本的数据库;.NET Data Provider for OLE DB包含在System.Data.OleDbClient命名空间中,用于管理OLE DB数据源的数据提供程序;.NET Data Provider for Oracle包含在System.Data.OracleClient命名空间中,用于连接Oracle 8或更高版本的数据库;.NET Data Provider for ODBC包含在System.Data.Odbc命名空间中,用于连接任何兼容ODBC的数据库。

.NET Data Provider含有4个对象:Connection、Command、DataReader和DataAdapter。这些对象都相应地派生出4个版本,分别位于上述的4个命名空间中。

在使用ASP.NET的数据库之前,必须先引用相应的命名空间,编写程序时,可以根据需要引用特定的命名空间,在aspx页引用命名空间的方法是使用Import命令。例如,要使用数据库SQL Server 2005,那么在所有程序的开头都要包含下面两条语句。

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClint" %>

(1) Connection对象

Connection对象用于打开到目标数据源的连接,让数据能够从数据源流向应用程序或者从应用程序流向数据源。Connection对象在各自的命名空间中派生出4个版本,因为在这里要连接SQL Server数据库,因此我们主要讲述SqlConnection对象,其他对象的属性请参考相关书籍。

SqlConnection对象提供的主要属性和方法分别如表2-1、2-2所示。

表2-1 SqlConnection对象的主要属性

表2-2 SqlConnection对象的方法

为了连接数据库,我们先建一个数据库work,并建一个数据表users。数据表users包括5个字段:id(序号、主键)、num(学号)、name(姓名)、college(学院)和subject(专业)。例如程序con-1.aspx,用SqlConnection与数据库源建立连接。

con-1.aspx页面代码比较简单,主要用于显示数据库是否已经连接,当单击连接数据库按钮时,如果能与数据库建立连接,则通过标签显示数据库已经连接,程序执行结果如图2-2所示。

图2-2 con-1.aspx执行结果

con-1.aspx主要代码如下:

      <body>
          <form id="form1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
            <asp:Button ID="Button1" runat="server" Text="连接数据库" />
          </form>
      </body>

con-1.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class Default2
          Inherits System.Web.UI.Page
          Protected Sub Button1_Click(ByVal sender As Object, ByVal e As
  System.EventArgs) Handles Button1.Click
            Dim conn As SqlConnection
            Dim constr As String
            constr = " server = localhost;database = work;uid=sa;pwd=123 "
          '创建SqlConnection对象
            conn = New SqlConnection(constr)
          '打开数据库连接
            conn.Open()
            Label1.Text = conn.State.ToString()
          '关闭数据库连接
            conn.Close()
          End Sub
      End Class

分析

当单击“连接数据库”时,通过函数Button1_Click()连接数据库,声明一个数据库连接对象conn,server用于指定SQL数据库所在的服务器名,可以用服务器的名称,也可以用IP地址;database用于指定连接的数据库名;uid和pwd用于指定要登录的SQL服务器的用户名和密码。通过标签来显示数据库连接的状态。

这里我们讲到的是通过SqlConnection对象连接数据库,也可以通过ODBC数据源连接数据库,只是这种方式要为数据库配置ODBC数据源。

(2) Command对象

Command对象用于执行与活动Connection对象相关的数据源上的存储过程或SQL语句,以及返回查询结果。创建Command对象后,可以使用ExecuteReader、ExecuteNonQuery和ExecuteScalar 3种类型的方法来执行命令语句。Command对象在各自的命名空间中派生出4个版本,我们主要讲述SqlCommand对象,其他对象的属性请参考相关书籍。

SqlCommand对象的属性和方法分别如表2-3、2-4所示。

表2-3 SqlCommand对象的主要属性

表2-4 SqlCommand对象的方法

在使用command对象之前,首先需要创建command对象,有两种方法可以创建command对象:一种是把Connection对象作为参数,使用Command构造函数完成Command对象实例化;另一种方法为使用Connection对象的CreatCommand方法来创建Command对象。

① 使用Command构造函数创建对象,构造函数有两个参数,一个是要执行的SQL语句,一个是所连接的Connection对象。例如:

Dim cm as SqlCommand = new SqlCommand("select * from users",conn)

② 使用Connection对象的CreatCommand()方法创建对象。例如:

Dim cm as SqlCommand =conn.CreatCommand()

cm.Commandtext="select * from users"

程序con-2.aspx,利用SqlCommand对象的ExecuteNonQuery()方法向数据库插入一行记录。

con-2.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class conn_2
          Inherits System.Web.UI.Page
          Protected Sub Button1_Click(ByVal sender As Object, ByVal e As
  System.EventArgs) Handles Button1.Click
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;database = work;uid=sa;pwd=123"
          '创建SqlConnection对象
          conn = New SqlConnection(constr)
          '打开数据库连接
          conn.Open()
          '创建SqlCommand对象
            Dim cmd As SqlCommand = New SqlCommand("insert into
  users(num,name,college,subject) values('1215655','bush','ouc','education')",
  conn)
            '执行插入数据
            cmd.ExecuteNonQuery()
            Response.Write("数据已插入")
          '关闭数据库连接
            conn.Close()
          End Sub
      End Class

分析

首先与数据库建立连接,然后创建一个SqlCommand对象cmd,利用方法ExecuteNonQuery()执行命令,此命令不返回任何数据。

(3) DataReader对象

使用Connection和Command对象与数据库连接并交互后,有两种方法来访问获取的结果。

① 使用DataReader对象,用来逐行从数据源中获取数据并处理。

② 使用DataSet对象,用来将数据存到内存中进行处理,将在后面内容中详细介绍。

DataReader可以看作一个从数据库源返回的仅向前的只读数据流。从头到尾往后读,并不缓存,而是读出后就处理,由于这种读法是一直独占数据库连接的(即在DataReader对象工作时,在与之关联的Connection对象上不能进行其他操作),所以,一般我们用这种读法时,要连续进行处理。这种读法长时间占用数据库连接的话,对数据库的影响是比较大的。所以,我们都是连续处理之后马上将它关闭。DataReader对象在各自的命名空间中派生出 4个版本,4个版本的属性和方法基本是一样的,我们这里主要讲述SqlDataReader对象。

SqlDataReader对象的属性和方法分别如表2-5、2-6所示。

表2-5 SqlDataReader对象的属性

表2-6 SqlDataReader对象的方法

与大多数其他ADO.NET类中的对象(它们是通过调用构造函数实例化的)不同, DataReader对象的创建是通过调用ExecuteReader()方法完成的。例如创建一个DataReader对象代码如下:

Dim myreader as SqlDataReader=cm.ExecuteReader()

SqlDataReader对象建立之后,就可以使用Read方法从查询结果中获得一个结果集,一个结果集对应一行数据。通常情况下,返回的结果记录不止一行,即多个结果集,为了获取所有的返回结果记录,使用SqlDataReader对象的Read方法(例如:XX.Read();)可以从查询结果依次取出一行。Read方法返回一个布尔值,返回True时,表示仍有记录未被读取,返回false时表示已经读完最后一条记录。

读取记录后,就可以获得每个记录中的某个字段,通过字段名或者字段的引用都可以获取记录中的某个字段,也可以使用SqlDataReader对象提供的更有效的查询方法——Get方法。Get方法可以根据所获得的字段类型不同,提供对应的不同的数据类型的方法。

程序con-3.aspx,利用SqlCommand对象的ExecuteReader()方法返回一个DataReader对象。用于显示查询数据库的信息,程序运行结果如图2-3所示。

图2-3 con-3.aspx运行结果

con-3.aspx代码如下:

      <body>
          <form id="form1" runat="server">
          <div>
            <asp:Label ID="Label1" runat="server" Height="43px" Width="114px">
  </asp:Label>
            <br />
            <br />
            <asp:Button ID="Button1" runat="server" Text="读取数据" /></div>
          </form>
      </body>

con-3.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class conn_3
          Inherits System.Web.UI.Page
      Protected Sub Button1_Click(ByVal sender As Object,ByVal e As System.EventArgs)Handles Button1.Click
          '声明SqlConnection对象
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;;database = work;uid=sa;pwd=123"
            conn = New SqlConnection(constr)
            '连接数据库
            conn.Open()
            '创建SqlCommand
            Dim cmd As SqlCommand = New SqlCommand("select * from users", conn)
          '通过SqlCommand的ExecuteReader()方法返回一个SqlDataReader对象
            Dim dr As SqlDataReader = cmd.ExecuteReader()
          '通过SqlDataReader 的 GetName方法输出各列的名称
      Label1.Text = "/" & dr.GetName(0) & "/" & dr.GetName(1) & "/" & dr.GetName(2)& "/" & dr.GetName(3) & "/" & dr.GetName(4) & "<br>"
          '通过While循环输出各列得值
            While dr.Read()
                Label1.Text = Label1.Text & "/" & dr.GetInt32(0) & "/" &
  dr.GetString(1) & "/" & dr.GetString(2) & "/" & dr.GetString(3) & "/" &
  dr.GetString(4) & "<br>"
            End While
            dr.close()
            conn.Close()
          End Sub
      End Class

分析

通过调用ExecuteReader()方法创建一个DataReader对象,然后利用Getname方法输出各列的名称,Read方法返回一个布尔值,返回True时,表示仍有记录未被读取,返回false时表示已经读完最后一条记录,通过while循环输出各条记录集,最后关闭DataReader对象。

(4) DataAdapter对象

上一节我们介绍了通过DataReader对象对查询结果进行读取和显示,除了使用DataReader对象对查询结果进行读取和显示外,还可以通过DataSet对象处理查询的结果。使用DataSet对象作为查询结果的处理方式时,对数据源执行查询和更改的就不再是Command对象,而是DataAdapter对象。DataAdapter对象的基本任务是作为DataSet对象和活动Connection对象所表示的数据源之间的链接。

具体的说,ADO.NET通过SqlDataAdapter对象建立、初始化DataTable(数据表)对象,从而和DatSet对象结合起来在内存中存放数据。SqlDataAdapter允许将DataSet对象中的数据保存到数据源(DataSource),也可以从数据源取出数据。DataAdapter类中包含一些特性,允许指定用于在DataSet和目标数据库之间起交互作用的实际SQL语句。换句话说, DataAdapter负责填充DataSet,并将DataSet中所做的修改发送回数据源。例如,DataAdapter类提供了控制要检索的数据的SelectCommand特性;指示如何将DataSet中的新数据添加到数据库中的InsertCommand特性;控制如何将DataSet中修改的记录传回到数据库的UpdateCommand特性;控制如何将DataSet中删除的行从数据库中删除的DeleteCommand特性。

SqlDataAdapter对象的属性和方法分别如表2-7、2-8所示。

表2-7 SqlDataAdapter对象的主要属性

表2-8 SqlDataAdapter对象的主要方法

SqlDataAdapter对象的创建与command对象的创建类似,例如:

Dim da as SqlDataAdapter = new SqlDataAdapter ("select * from users",conn):

程序con-4.aspx,利用SqlDataAdapter对象查询数据库中信息,并输出数据。程序运行结果如图2-4所示。

图2-4 con-4.aspx运行结果

con-4.aspx代码如下:

      <body>
          <form id="form1" runat="server">
          <div>
            &nbsp;<asp:GridView ID="GridView1" runat="server">
            </asp:GridView>
          </div>
          </form>
      </body>

con-4.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class conn_4
          Inherits System.Web.UI.Page
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)Handles Me.Load
          '声明一个SqlConnection对象
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;database = work;uid=sa;pwd=123"
            conn = New SqlConnection(constr)
            '打开数据库连接
            conn.Open()
            Dim sql As String = "select * from users"
          '创建一个SqlDataAdapter对象
            Dim da As SqlDataAdapter = New SqlDataAdapter(sql, conn)
            '创建一个DataSet对象
            Dim ds As DataSet = New DataSet()
            '将da中的数据放入ds中
            da.Fill(ds)
            '将数据绑定到GridView1
            GridView1.DataSource = ds
            GridView1.DataBind()
        End Sub
      End Class

分析

在本例中通过SqlDataAdapter对象获取查询结果,并通过fill方法把查询结果放到DataSet对象(DataSet对象将在下一节详细说明)中,最后将DataSet对象邦定到GridView输出。

通过SqlDataAdapter对象的InsertCommand、UpdateCommand和DeleteCommand属性可以完成对数据库的插入、更新和删除操作,这些内容将在DataSet一节中介绍。

2. .NET DataSet

新的ADO.NET体系结构的中心是DataSet。DataSet位于.NET Framework中的System.Data.DataSet中。DataSet实际上是从数据库中检索的记录的缓存。DataSet是数据的内存驻留表示形式,无论数据源是什么,它都会提供一致的关系编程模型。可以用于多种不同的数据源,用于XML数据,或用于管理应用程序本地的数据。您可以将DataSet当作一个小型数据库。DataSet包含表、列、约束、行和关系。这些DataSet对象称为DataTable、DataColumn、DataRow、Constraint和Reliation,DataSet体系结构如图2-5所示。DataSet实际上允许使用无连接的应用程序,就好像它被主动地连接到数据库。应用程序通常需要访问相关数据库信息的多个部分,从而为终端用户提供有用的信息。例如,要处理一项任务,应用程序通常需要访问大量不同的数据库表,这一组表中的所有相关信息都可以组合到DataSet中,这为无连接的应用程序提供了使用所需的全部相关订单信息的功能。

图2-5 DataSet体系结构

在无连接模式下,返回数据源获取相关信息的各个不同部分的效率比较低,因此DataSet一般通过活动Connection对象和相应.NET Data Provider中的DataAdapter一次性地填入所有信息。在填充DataSet时会临时打开一个数据库连接,结束后再将它关闭。然后DataSet就可以独立于后台数据库进行操作。接下来,客户端应用程序可以访问DataSet中包含的Table、DataRow、DataColumn以及DataView对象。所有对DataSet中数据的修改都会通过DataAdapter对象传回到数据库。

在多层环境中,可以使用GetChanges方法创建一个包含所有修改数据的DataSet副本。然后将这个DataSet副本作为DataAdapter的Update方法的参数,将修改传送到目标数据库。如果这个DataSet副本中的数据发生变化,则可以使用DataSet的Merge方法将这些变化传送到原始的DataSet。

(1) DataSet对象

DataSet对象是一个体系,它包含表、列、约束、行和关系。DataSet对象可以包含许多个DataTable对象,每个DataTable对象对应于数据库中的一张表或视图。一个DataTable又通常有许多行(DataRow)和列(DataColumn)组成,DataTable对象还可以包含表的约束、索引和关系,这些信息都以XML的形式存在,以便于处理或索引任意数据。DataTable之间的关系通过DataRelationCollection属性来表示,如果没有任何关系,该属性值为null,每个关系由DataRelation对象表示,它将两个DataTable对象通过DataColumn对象的匹配关系联系起来,每个DataRow对象都有一个GetChildRows和GetParentRows方法,用于返回一组通过DataRelation实现关联的DataRowsCollection对象。

(2) DataTable对象

DataTable位于.NET Framework的System.Data.DataTable中。DataTable对象表示DataSet对象中包含的内存数据的表。通过将DataAdapter中的结果集返回到DataSet对象,可以自动创建DataTable对象,也可以先声明一个DataTable对象,然后再添加到DataSet中。通过向DataTable的DataColumn集合中添加DataColumn对象也可以创建DataTable对象。

在修改DataTable对象中包含的数据时,会激活ColumnChanging、ColumnChanged、RowChanging和RowChanged事件。在删除DataTable对象中的数据时,会激活RowDeleting和RowDeleted事件。通过调用DataTable的NewRow方法并向该方法传递一个DataRow对象,可以向DataTable中添加新行。它还可以作为创建DataView对象的基础。

例如:创建一个DataTable对象,并加入到DataSet中。

      Dim ds As New DataSet()
      Dim mytable As DataTable=New DataTable("table1")
      Dim mycolumn As DataColumn
      Dim myrow As DataRow
      '创建一列
      mycolumn= New DataColumn()
      mycolumn.DataType=System.Type.GetType("System.Int32")
      mycolumn.ColumnName="sid"
      '把列添加到表中
      mytable.Column.Add(mycolumn)
      '创建一列
      mycolumn= New DataColumn()
      mycolumn.DataType=System.Type.GetType("System.String")
      mycolumn.ColumnName="name"
      '把列添加到表中
      mytable.Column.Add(mycolumn)
      '把行加入到表中
      myrow=mytable.NewRow()
      myrow("sid")=1
      myrow("name")="bush"
      mytable.Rows.Add(myrow)

(3) DataColumn对象

DataColumn位于.NET Framework的System.Data.DataColumn中。它表示DataTable对象中某个列的模式。DataColumn类包含一些特性,用于定义DataColumn对象中包含的数据的类型。DataType特性控制DataColumn对象中可以保存的数据类型;DataValue特性包含DataColumn的值;AllowDBNull特性指定DataColumn是否可以包含NULL值;MaxLength特性设置Text DataType的最大长度;Table特性指定DataColumn所属的DataTable对象。通过创建一个DataRelation对象并将它添加到该DataSet的DataRelationCollection,你可以将一个DataColumn对象与另一个DataColumn对象关联。

例如,创建DataColumn对象,并添加到表中。

      mycolumn= New DataColumn()
      mycolumn.DataType=System.Type.GetType("System.Int32")
      mycolumn.ColumnName="sid"
      '把列添加到表中
      mytable.Column.Add(mycolumn)

(4) DataRow对象

DataRow位于.NET Framework的System.Data.DataRow中,它表示DataTable对象中的一行数据。DataRow类和DataColumn类表示组成DataTable类的主要对象。DataRow对象用于插入、更新和删除DataTable中的行。通过使用NewRow方法创建一个新的DataRow对象,或者通过向DataSet的DataRowCollection中添加DataRow对象,可以向DataTable中添加行。通过简单地修改DataRow对象的DataValue特性,可以更新DataRow对象。通过执行DataRow对象的Delete方法或调用DataSet的DataRowCollection对象的Remove方法,可以删除DataRow对象。

例如,创建DataRow对象,并添加到表中。

myrow=mytable.NewRow()

myrow("sid")=1

myrow("name")="bush"

mytable.Rows.Add(myrow)

(5) DataView对象

DataView位于.NET Framework的System.Data.DataView中,它为DataTable对象中行的子集提供了自定义的视图。与基本DataTable对象提供的数据相比,DataView类的RowFilter和Sort特性允许按照不同的顺序显示DataView提供的数据。与DataTable对象一样,DataView对象中包含的数据也是可以更新的。您可以使用AddNew方法添加新行,或使用Delete方法删除行。

(6) DataRelation对象

DataRelation位于.NET Framework的System.Data.DataRelation中。DataRelation用于表示DataSet中两个DataTable对象之间的父子关系。为了在两个DataTable对象中创建一个关系,这两个DataTable包含的DataColumn对象必须具备匹配的特性。在首次创建DataRelation时,.NET Framework检查以确保该关系有效,然后将这个DataRelation对象添加到DataRelationCollection中,其中记录了与该DataSet相关的所有数据。

(7) DataSet使用

DataSet对象是与数据源无关的新的数据表示方式,为了引入和容纳数据源的数据, DataSet对象必须要和DataAdapter对象配合使用。DataSet对象与数据源无关,DataAdapter对象充当了DataSet对象和实际数据之间的桥梁,它可以用来向DataSet对象填充数据,并将DataSet对象中数据的改变反映到实际数据库中进行更新。

有关使用DataSet对象访问数据库,并将数据库中的内容显示出来的方法在前面讲述SqlDataAdapter对象时已经讲到,通过Connection对象连接数据库,通过SqlDataAdapter对象获取查询结果,并用fill方法把查询结果放到DataSet对象中,最后将DataSet对象邦定到GridView输出。

通过DataSet对象对数据库操作(插入、删除和更新记录)其实是对内存的数据进行操作,也必须使用SqlDataAdapter对象更新真正的数据表记录数据。操作步骤如下:

① 创建Connection对象,连接数据库。

② 创建SqlDataAdapter对象。

③ 创建DataSet对象,并填入记录数据。

④ 在DataTable中执行数据库操作。

⑤ 更新数据表的记录数据,并关闭数据库。

例如程序con-5.aspx,通过DataSet对象向数据库插入新记录。

con-5.aspx代码如下:

      <body>
          <form id="form1" runat="server">
          <div>
              <asp:Button ID="Button1" runat="server" Height="30px" Text="插入新记录" Width="82px" /></div>
          </form>
      </body>

con-5.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class conn_5
          Inherits System.Web.UI.Page
          Protected Sub Button1_Click(ByVal sender As Object, ByVal e As
  System.EventArgs) Handles Button1.Click
            Dim conn As SqlConnection
            Dim constr As String
            Dim count As Integer
            constr = "server = localhost;;database = work;uid=sa;pwd=123"
            '创建connection对象
            conn = New SqlConnection(constr)
            conn.Open()
            Dim sql As String = "select * from users"
            '创建dataadapter对象
            Dim da As SqlDataAdapter = New SqlDataAdapter(sql, conn)
            '创建CommandBuilder对象
            Dim cmdbuilder As SqlCommandBuilder = New SqlCommandBuilder(da)
            '创建DataSet对象
            Dim ds As DataSet = New DataSet()
            '将数据填入DataSet对象
            da.Fill(ds, "users")
            Dim myrow As DataRow
            '新建一行
            myrow = ds.Tables("users").NewRow()
            myrow("num") = "005"
            myrow("name") = "xiaoli"
            myrow("college") = "tsinghua"
            myrow("subject") = "election"
            '添加一行
            ds.Tables("users").Rows.Add(myrow)
            '使数据库内容和DataSet对象的内容保持一致
            count = da.Update(ds, "users")
            If count = 1 Then
                Response.Write("插入数据库成功")
            End If
            conn.Close()
        End Sub
      End Class

分析

对DataSet对象插入一条新记录操作是对DataTable对象增加一行(DataRow对象),创建CommandBuilder对象,当修改DataSet对象时,自动创建操作数据库所需的SQL语句,通过Updata语句使数据库内容和DataSet对象的内容保持一致。

例如程序con-6.aspx,通过DataSet对象更新数据库中的记录。

con-6.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class conn_6
          Inherits System.Web.UI.Page
          Protected Sub Button1_Click(ByVal sender As Object, ByVal e As
  System.EventArgs) Handles Button1.Click
            Dim conn As SqlConnection
            Dim constr As String
            Dim count As Integer
            constr = "server = localhost;;database = work;uid=sa;pwd=123"
            '创建connection对象
            conn = New SqlConnection(constr)
            conn.Open()
            Dim sql As String = "select * from users"
            '创建dataadapter对象
            Dim da As SqlDataAdapter = New SqlDataAdapter(sql, conn)
            '创建CommandBuilder对象
            Dim cmdbuilder As SqlCommandBuilder = New SqlCommandBuilder(da)
            '创建DataSet对象
            Dim ds As DataSet = New DataSet()
            '将数据填入DataSet对象
            da.Fill(ds, "users")
            Dim myrow As DataRow
            For Each myrow In ds.Tables("users").Rows
                If myrow("num") = "005" Then
                    myrow("name") = "xiaozhang"
                    myrow("college") = "bju"
                    myrow("subject") = "math"
                End If
            Next
            '使数据库内容和DataSet对象的内容保持一致
            count = da.Update(ds, "users")
            conn.Close()
        End Sub
      End Class

分析

更新数据库中的记录与向数据库插入一条新记录原理是一样的,都是要修改DataSet对象中的DataTable,将数据库内容和DataSet对象的内容保持一致。

如果要删除数据库中的一条记录与上例一样,通过DataRow对象的Delete()方法即可以实现。

2.1.3 数据访问服务器控件

上一节讲述了操作数据库的内容,对ADO.NET有了一定的了解,这一节我们将介绍有关数据访问服务器控件,也就是有关网页数据库的显示和维护的控件,主要包括数据源控件、Repeater控件、DataGrid控件、DataList控件、GridView控件、DetailsView控件以及FormView控件。这里我们主要介绍Repeater控件、DataList控件和GridView控件。

1. Repeater控件

Repeater控件是个轻量级的数据绑定控件,一般用它来输出要求相对简单的数据, Repeater控件是一个可重复操作的控件,类似于For/Next循环,没有预定义的外观,显示什么内容以及如何显示内容需要使用模板,它没有内置的布局样式,必须在此控件的模板内使用HTML标记设置样式和格式。

Repeater控件支持的模板类型如表2-9所示。

表2-9 Repeater控件支持的模板类型

在上一节中,我们建立了数据库work,创建了数据表users,以这个数据库为基础,用Repeater控件显示数据库中的内容,程序运行结果如图2-6所示。

图2-6 repeater.aspx运行结果

repeater.aspx代码如下:

      <body>
          <form id="form1" runat="server">
          <div>
        <%--创建一个Repeater对象--%>
      <asp:Repeater ID="Repeater1" runat="server">
          <HeaderTemplate>
          <table width="100%" border="1">
            <tr bgcolor="#999999">
              <td>学号</td>
              <td>姓名</td>
              <td>学院</td>
              <td>专业</td>
            </tr>
          </HeaderTemplate>
        <%--显示每行数据--%>
      <ItemTemplate>
          <tr bgcolor=#ffffff>
            <td><%# eval("num") %></td>
            <td><%# eval("name") %></td>
            <td><%# eval("college") %></td>
            <td><%# eval("subject") %></td>
            </tr>
         </ItemTemplate>
         <AlternatingItemTemplate>
          <tr bgcolor=#f5f2f7>
            <td><%# eval("num") %></td>
            <td><%# eval("name") %></td>
            <td><%# eval("college") %></td>
            <td><%# eval("subject") %></td>
            </tr>
         </AlternatingItemTemplate>
         <FooterTemplate>
          </table>
         </FooterTemplate>
       </asp:Repeater>
          </div>
         </form>
      </body>

repeater.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class repeat
          Inherits System.Web.UI.Page
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)Handles Me.Load
            Dim conn As SqlConnection
            Dim constr As String
            Dim count As Integer
            constr = "server = localhost;;database = work;uid=sa;pwd=123"
            '创建connection对象
            conn = New SqlConnection(constr)
            conn.Open()
            Dim sql As String = "select * from users"
            Dim cmd As SqlCommand = New SqlCommand(sql, conn)
            Dim dr As SqlDataReader = cmd.ExecuteReader()
            '将dr对象中的数据绑定到Repeater1
            Repeater1.DataSource = dr
            Repeater1.DataBind()
            conn.Close()
          End Sub
      End Class

分析

上例中通过将数据库查询的数据绑定到Repeater控件上,然后通过模板将数据显示出来。Repeater控件格式是通过它支持的模板类型实现的,它本身不能实现数据的编辑、修改和删除的操作,但可以通过它所提供的ItemCommand方法进一步编程,从而区分不同控件触发的事情,最终也能实现编辑、修改和删除的操作,用Repeater控件实现这些功能相对比较麻烦,一般通过别的控件完成。

2. DataList控件

DataList控件和Repeater控件类似,它的数据显示和布局也是通过模板来控制的,但新增了两种模板类型,SelectedItemTemplate模板和EditItemTemplate模板,分别用于选择和修改数据项的内容。

DataList控件支持的模板类型如表2-10所示。

表2-10 DataList控件支持的模板类型

表2-11 DataList控件事件

以上面所建的数据库work为数据源,通过DataList控件显示数据信息。使用Visual Studio 2008开发工具,首先把DataList控件拖入DataList.aspx页面,用鼠标单击右键可以看到“自动套用格式”选项,界面如图2-7所示。

图2-7 自动套用格式

自动套用格式面板中提供了一些选择方案,可以选择其中一种,也可以自己设置DataList控件显示的格式。选择某种格式方案后,DataList格式代码如下。

      <asp:DataList ID="DataList1" runat="server" BackColor="LightGoldenrodYellow"BorderColor="Tan" BorderWidth="1px" CellPadding="2" ForeColor="Black">
                <FooterStyle BackColor="Tan" />
                <SelectedItemStyle BackColor="DarkSlateBlue"
  ForeColor="GhostWhite" />
                <AlternatingItemStyle BackColor="PaleGoldenrod" />
                <HeaderStyle BackColor="Tan" Font-Bold="True" />
      </asp:DataList>

单击鼠标右键,从弹出的快捷菜单中选择“编辑模板”→“页眉和页脚模板”选项,如图2-8所示。在这里可以设置显示的页眉和页脚。

图2-8 页眉和页脚

单击鼠标右键,从弹出的快捷菜单中选择“编辑模板”→“分隔符模板”选项,如图2-9所示。在这里可以设置分隔符。

图2-9 分隔符模板

单击鼠标右键,从弹出的快捷菜单中选择“编辑模板”→“项模板”选项,如图2-10所示。在这里可以设置ItemTemplate、AlternatingItemTemplate、EditItemTemplate和SelectedItemTemplate模板。

图2-10 项模板

单击鼠标右键,查看属性生成器控件,如图2-11所示。属性生成器控件包括常规、格式和边框3个选项卡,这里可以设置页眉、页脚、重复布局的列数、方向和布局方式。

图2-11 属性生成器控件

Datalist.aspx设置完成后的运行结果如图2-12所示。

图2-12 Datalist.aspx运行结果

Datalist.aspx代码如下:

      <body>
          <form id="form1" runat="server">
      <div>
          <%--创建一个DataList对象--%>
            <asp:DataList ID="DataList1" runat="server"
  BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px"
  CellPadding="2" ForeColor="Black" GridLines="Horizontal" RepeatColumns="0">
                <FooterStyle BackColor="Tan" />
                <SelectedItemStyle BackColor="DarkSlateBlue"
  ForeColor="GhostWhite" />
                <AlternatingItemStyle BackColor="PaleGoldenrod" />
                <HeaderStyle BackColor="Tan" Font-Bold="True" />
                <HeaderTemplate>
                    清华大学
                </HeaderTemplate>
                <FooterTemplate>
                    <strong>学生信息</strong>
                </FooterTemplate>
                <ItemTemplate>
                    学号:<%#Eval("num")%>姓名:<%#Eval("name")%>学院:
  <%#Eval("college")%>专业<%#Eval("subject")%>
@@@
                </ItemTemplate>
            </asp:DataList></div>
          </form>
      </body>

Datalist.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class datalist
        Inherits System.Web.UI.Page
        Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs)Handles Me.Load
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;database = work;uid=sa;pwd=123"
            '创建connection对象
            conn = New SqlConnection(constr)
            conn.Open()
            Dim sql As String = "select * from users"
            '创建SqlCommand对象
            Dim cmd As SqlCommand = New SqlCommand(sql, conn)
        '创建一个SqlDataReader对象
            Dim dr As SqlDataReader = cmd.ExecuteReader()
            '将数据绑定到DataList1
            DataList1.DataSource = dr
            DataList1.DataBind()
            conn.Close()
        End Sub
    End Class

DataList控件提供了数据编辑功能,可以利用此功能修改、删除数据信息。Datalist1.aspx程序运行结果如图2-13所示。单击“编辑”超链接按钮,弹出的界面如图2-14所示。

图2-13 Datalist.aspx程序运行结果

图2-14 更新、删除信息界面

Datalist1.aspx代码如下:

          <body>
              <form id="form1" runat="server">
          <div>
              <%--创建一个DataList 对象--%>
                <asp:DataList ID="DataList2" runat="server" OnEditCommand="bianji"
      DataKeyField="id" OnDeleteCommand="delete" OnCancelCommand="cancel"
      OnUpdateCommand="update">
                    <FooterStyle BackColor="Tan" />
                    <SelectedItemStyle BackColor="DarkSlateBlue"
      ForeColor="GhostWhite" />
                <AlternatingItemStyle BackColor="PaleGoldenrod" />
                <HeaderStyle BackColor="Tan" Font-Bold="True" />
                <HeaderTemplate>
                    清华大学
                </HeaderTemplate>
                <FooterTemplate>
                    <strong>学生信息</strong>
                </FooterTemplate>
                <ItemTemplate>
                    学号:<%#Eval("num")%>姓名:<%#Eval("name")%>学院:
  <%#Eval("college")%>专业<%#Eval("subject")%>
                <%--设置编辑按钮的CommandName 属性--%>
                    <asp:LinkButton ID="LinkButton1" runat="server"  Text='编辑'
  CommandName="edit"></asp:LinkButton>
                  </ItemTemplate>
                <%--编辑魔板--%>
              <EditItemTemplate>
                id:<%#Eval("num")%><br />学号:<asp:TextBox ID="num" runat="server"Text='<%#Eval("num")%>' /><br />
                姓名:<asp:TextBox ID="name" runat="server" Text='<%#Eval("name")%>'/><br />
                学院:<asp:TextBox ID="college" runat="server"Text='<%#Eval("college")%>' /><br />
                专业:<asp:TextBox ID="subject" runat="server"Text='<%#Eval("subject")%>' /><br /><asp:LinkButton id="button0" Text='更新' CommandName="update"
                runat="server" /><asp:LinkButton ID="Button1" Text='删除' CommandName="delete"
                runat="server" /><asp:LinkButton ID="Button2" Text='取消' CommandName="cancel"
                runat="server" />
              </EditItemTemplate>
              </asp:DataList>&nbsp;</div>
          </form>
      </body>

Datalist1.aspx.vb中主要包括一个SqlDataAdapter全局变量和6个事件。

SqlDataAdapter全局变量定义在事件之外,代码如下:

Public da As SqlDataAdapter

Page_Load事件代码如下:

      '通过Page_Load事件绑定数据源
          Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs)Handles Me.Load
            If Not IsPostBack Then
                Call BindData()
            End If
      End Sub

数据绑定事件代码如下:

          Sub BindData()
              Dim conn As SqlConnection
              Dim constr As String
              constr = "server = localhost;database = work;uid=sa;pwd=123"
              '创建connection对象
              conn = New SqlConnection(constr)
              conn.Open()
              Dim sql As String = "select * from users"
          '创建SqlDataAdapter对象
              da = New SqlDataAdapter("select * from users", conn)
          '创建DataSet对象
              Dim ds As DataSet = New DataSet()
              da.Fill(ds, "users")
              '将数据绑定到DataList2
              DataList2.DataSource = ds
              DataList2.DataBind()
      End Sub

当单击“编辑”按钮时触发的edit事件代码如下:

          Sub bianji(ByVal sender As Object, ByVal e As DataListCommandEventArgs)
              '获得编辑行的索引值
          DataList2.EditItemIndex = e.Item.ItemIndex
          '重新绑定数据源
              Call BindData()
      End Sub

当单击“更新”按钮触发时的update事件代码如下:

        Sub update(ByVal sender As Object, ByVal e As DataListCommandEventArgs)
            Dim num As TextBox = e.Item.FindControl("num")
            Dim name As TextBox = e.Item.FindControl("name")
            Dim college As TextBox = e.Item.FindControl("college")
            Dim subject As TextBox = e.Item.FindControl("subject")
            Dim str As String
            str="UPDATE    users   SET  num='"&num.Text&"',name='"&name.Text& "',college='" & college.Text & "',subject='" & subject.Text & "'  WHERE  id =" & DataList2.DataKeys(CInt(e.Item.ItemIndex))
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;database = work;uid=sa;pwd=123"
            conn = New SqlConnection(constr)
            conn.Open()
            Dim cmd As SqlCommand = New SqlCommand(str, conn)
            cmd.ExecuteNonQuery()
            DataList2.EditItemIndex = -1
            '重新绑定数据源
            Call BindData()
        End Sub

当单击“删除”按钮触发时的delete事件代码如下:

        Sub delete(ByVal sender As Object, ByVal e As DataListCommandEventArgs)
            Dim str As String
            str = "delete from users where id=" &
  DataList2.DataKeys(CInt(e.Item.ItemIndex))
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;database = work;uid=sa;pwd=123"
            conn = New SqlConnection(constr)
            conn.Open()
            Dim cmd As SqlCommand = New SqlCommand(str, conn)
            cmd.ExecuteNonQuery()
            DataList2.EditItemIndex = -1
            '重新绑定数据源
            Call BindData()
    End Sub

当单击“取消”按钮触发时的cancel事件代码如下:

          Sub cancel(ByVal sender As Object, ByVal e As DataListCommandEventArgs)
              DataList2.EditItemIndex = -1
              '重新绑定数据源
              Call BindData()
      End Sub

分析

DataList提供了编辑功能,程序中提供了 4个超链接按钮:编辑、更新、删除和取消。这四个按钮分别对应的属性为edit、update、delete和cancel。当单击这4个按钮时分别触发不同的事件,编辑按钮触发事件edit,更新按钮触发事件update,删除按钮触发事件delete,取消按钮触发事件cancel。

3. GridView控件

DataGrid控件是一个非常通用的数据绑定控件,由于在ASP.NET 2.0之后推出了网格控件GridView,将DataGrid控件的功能加入到控件GridView中,因此,本节我们将重点介绍控件GridView。

在GridView控件指定使用的数据源,就可以使用默认的表格样式来显示数据记录。例如con-4.aspx就是利用GridView控件默认的表格样式显示数据。GridView控件能够自动产生Field控件的表格字段,GridView控件的常用属性如表2-12所示。

表2-12 GridView控件的常用属性

GridView控件能够自动产生所需要的字段,如果需要更多的字段,可以将AutoGenerateColumns属性设为false,然后在<Column>标识段添加Field控件,Field控件的常用字段如表2-13所示。

表2-13 Field控件的常用字段

例如,GridView.aspx用不同的Field字段显示数据,运行结果如图2-15所示。

图2-15 GridView.aspx运行结果

GridView.aspx代码如下:

      <body>
          <form id="form1" runat="server">
          <div>
            <asp:GridView ID="GridView1" runat="server"
  AutoGenerateColumns="false">
      <Columns>
      <asp:BoundField HeaderText="学号" DataField="num" />
      <asp:ButtonField ButtonType="Button" HeaderText="姓名" DataTextField="name"
  />
      <asp:ButtonField ButtonType="Button" HeaderText="学院"
  DataTextField="college" />
      <asp:HyperLinkField HeaderText="专业" DataTextField="subject" />
      </Columns>
            </asp:GridView>
          </div>
          </form>
      </body>

GridView.aspx.vb主要代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class gridview
          Inherits System.Web.UI.Page
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)Handles Me.Load
          '声明一个SqlConnection对象
            Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;database = work;uid=sa;pwd=123"
            conn = New SqlConnection(constr)
            '打开数据库连接
            conn.Open()
            Dim sql As String = "select * from users"
          '创建一个SqlDataAdapter对象
            Dim da As SqlDataAdapter = New SqlDataAdapter(sql, conn)
            '创建一个DataSet对象
            Dim ds As DataSet = New DataSet()
            '将da中的数据放入ds中
            da.Fill(ds)
            '将数据绑定到GridView1
            GridView1.DataSource = ds
            GridView1.DataBind()
          End Sub
      End Class

GridView控件提供了强大的编辑和分页功能,使用起来比DataList控件要方便,由于DataList控件中已经详细讲了编辑功能,这里主要介绍GridView控件的分页功能,例如程序GridView1.aspx分页显示效果如图2-16所示。

图2-16 GridView1.aspx分页显示效果

GridView1.aspx代码如下:

      <body>
          <form id="form1" runat="server">
          <div>
              <asp:GridView ID="GridView2" runat="server"
  AutoGenerateColumns="false" AllowPaging="True" PageSize="2"
  PagerSettings-Position="TopAndBottom"  PagerSettings-Mode="NextPrevious">
      <Columns>
      <asp:BoundField HeaderText="学号" DataField="num" />
      <asp:ButtonField ButtonType="Button" HeaderText="姓名" DataTextField="name"
  />
      <asp:ButtonField ButtonType="Button" HeaderText="学院"
  DataTextField="college" />
      <asp:HyperLinkField HeaderText="专业" DataTextField="subject" />
      </Columns>
            </asp:GridView>
          </div>
          </form>
      </body>

GridView1.aspx.vb代码如下:

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      Partial Class gridview1
      Inherits System.Web.UI.Page
      'Page_Load事件主要用于查询数据库,帮数据绑定到GridView2
          Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs)Handles Me.Load
            '声明SqlConnection对象
          Dim conn As SqlConnection
            Dim constr As String
            constr = "server = localhost;;database = work;uid=sa;pwd=123"
            conn = New SqlConnection(constr)
            conn.Open()
            Dim sql As String = "select * from users"
            '创建SqlDataAdapter对象
            Dim da As SqlDataAdapter = New SqlDataAdapter(sql, conn)
            Dim ds As DataSet = New DataSet()
            '将查询的数据填充到ds
            da.Fill(ds)
              '绑定数据到GridView2
            GridView2.DataSource = ds
            GridView2.DataBind()
            conn.Close()
      End Sub
      'GridView2_PageIndexChanging用于重新获得页码的索引值,并重新绑定数据源
      Protected Sub GridView2_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles
  GridView2.PageIndexChanging
          '重新获得页码的索引值
              GridView2.PageIndex = e.NewPageIndex
          '重新绑定数据源
              GridView2.DataBind() '
          End Sub
      End Class

分析

GridView控件提供了分页功能,AllowPaging属性设置为True,表示可以分页, PageSize属性表明每页显示的记录数,PagerSettings-Position表示页码显示的位置。注意在GridView1.aspx.vb中有分页处理事件PageIndexChanging,执行分页时触发此事件。GridView控件可以在不编写任何程序代码的情况下,实现编辑、分页和排序功能,在后面的章节中将会讲到。