- Web开发的贵族:ASP.NET 3.5+SQL Server 2008
- 陈凤鸣 付海东 孙更新等编著
- 9146字
- 2020-08-27 07:50:50
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> <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> </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控件可以在不编写任何程序代码的情况下,实现编辑、分页和排序功能,在后面的章节中将会讲到。