4.5 DataSet
学习目标
掌握DataSet的详细使用方法。
本节示例代码参考:/Code/ch04/StudyDataSet。
4.5.1 DataSet概述
可以说ADO.NET中技术的最大飞跃就是引入了DataSet技术,使用该技术可以把数据库的访问转换到DataSet数据集中,以此减轻数据库的访问负担,传统ADO技术访问数据库就是每次与数据库相关的操作都要直接访问数据库,特别是在Web环境下,多个终端访问服务器系统,导致系统资源竞争变得更加强烈。而ADO.NET技术中的DataSet数据集的引入,使得用户要访问数据库中的信息,不需要直接和数据库交互,直接和DataSet数据集交互访问即可,最后DataSet数据集再集中一次把所有引起数据变化的信息更新到数据库,实际上就是给出了一个数据访问的缓冲机制。
DataSet对象是支持ADO.NET的断开式、分布式数据方案的核心对象。DataSet是数据的内存驻留表示形式,无论数据源是什么,它都会提供一致的关系编程模型。它可以用于多种不同的数据源,用于XML数据,或用于管理应用程序本地的数据。DataSet表示包括相关表、约束和表间关系在内的整个数据集。
具体来说,DataSet对象是一个用于存放数据的大集合。DataSet对象当中可以存放若干个DataTable数据表对象,而每个DataTable数据表中的数据则由DataAdapter对象来填充。因此从使用角度来看,DataSet数据集对象就像一个内存中处于活动状态的数据库,数据库中仍然有多个数据表,每个数据表中有多个数据行(DataRow),每个数据行中又有多个数据列(DataColumn)。这种层次关系和一般的数据库、数据表概念非常相似。
DataSet数据集,类似于内存数据库,其中包括DataTable、DataRow、Data Column等相关对象。图4-29给出了DataSet数据集常用对象的使用关系。
由图4-29可以看出ADO.NET DataSet包含由DataTable对象表示的零个或多个表的集合。DataTableCollection包含DataSet中的所有DataTable对象。
DataTable在System.Data命名空间中定义,表示内存驻留数据的单个表。其中包含由DataColumnCollection表示的列集合以及由ConstraintCollection表示的约束集合,这两个集合共同定义表的架构。DataTable还包含DataRowCollection所表示的行的集合,而DataRowCollection则包含表中的数据。除了其当前状态之外,DataRow还会保留其当前版本和初始版本,以标识对行中存储的值的更改。
DataSet在其DataRelationCollection对象中包含关系。关系由DataRelation对象来表示,它使一个DataTable中的行与另一个DataTable中的行相关联。关系类似于可能存在于关系数据库中的主键列和外键列之间的连接路径。DataRelation标识DataSet中两个表的匹配列。
通过关系可以从DataSet中的一个表导航至另一个表。DataRelation的基本元素为关系的名称、相关表的名称以及每个表中的相关列。关系可以通过一个表的多个列来生成,方法是将一组DataColumn对象指定为键列。将关系添加到DataRelationCollection中之后,可以选择添加UniqueKeyConstraint和ForeignKeyConstraint,在对相关列的值进行更改时,强制执行完整性约束。
在典型的多层实现中,用于创建和刷新 DataSet并依次更新原始数据的步骤如下。
(1)通过 DataAdapter使用数据源中的数据生成和填充 DataSet中的每个 DataTable。
(2)通过添加、更新或删除 DataRow对象更改单个 DataTable对象中的数据。
(3)调用GetChanges方法以创建只反映对数据进行的更改的第二个 DataSet。
(4)调用DataAdapter的Update方法,并将第二个DataSet作为参数传递。
(5)调用Merge方法将第二个DataSet中的更改合并到第一个中。
(6)针对DataSet调用AcceptChanges。或者,调用RejectChanges以取消更改。
4.5.2 创建DataSet数据集
可以通过调用DataSet构造函数来创建DataSet的实例。可以选择指定一个名称参数。如果没有为 DataSet指定名称,则该名称会设置为“NewDataSet”。例如,使用如下代码创建了两个DataSet数据集,其中ds1的名称为“new DataSet”,而ds2的名称为“myDS”。
DataSet ds1 = new DataSet(); Response.Write(ds1.DataSetName + "<br />"); DataSet ds2 = new DataSet("myDS"); Response.Write(ds2.DataSetName + "<br />");
由于DataSet是由多个DataTable组成的集合,故没有DataTable的DataSet没有实际意义,所以创建完DataSet数据集后一般都会给其添加相关的DataTable。
4.5.3 给DataSet添加DataTable
除了使用DataAdapter数据适配器对象向DataSet中添加DataTable外,也可以直接定义DataTable并将其添加到指定的DataSet中。
这里要举的例子就是首先定义一个DataSet,然后给其添加两张DataTable表,最后把DataSet中的表绑定到页面的两个不同的GridView中。接下来给出完整步骤和代码。
(1)新建ASP.NET网站项目StudyDataSet,删除默认Default.aspx页面,添加页面StudyDataSet002.aspx。在页面StudyDataSet002.aspx的设计窗口添加两个GridView控件作为显示数据信息的容器,并使用div水平布局,需要给div增加样式float为left,StudyDataSet002.aspx的设计窗口显示效果如图4-30所示,设计窗口完整的HTML源代码如下。
<form id="form1" runat="server"> <div style="width: 200px; float: left;"> 表table001<br /> <asp:GridView ID="GridView1" runat="server"> </asp:GridView> </div> <div style="width: 200px; float: left;"> 表table002<br /> <asp:GridView ID="GridView2" runat="server"> </asp:GridView> </div> </form>
(2)直接进入StudyDataSet002.aspx的代码窗口,编写完整Page_Load初始化代码如下,其中编写了大量注释,方便读者阅读。
protected void Page_Load(object sender, EventArgs e) { //定义一个DataSet对象ds,命名为myDS DataSet ds = new DataSet("myDS"); //给ds添加一个DataTable命名为table001,并实例化为dt001 DataTable dt001 = ds.Tables.Add("table001"); //给dt001添加列id dt001.Columns.Add("id"); //给dt001添加列item dt001.Columns.Add("item"); //通过循环方式给dt001添加10行记录 for (int index = 1; index <= 10; index++) { //以dt001的架构为结构实例化一个DataRow对象 DataRow dr = dt001.NewRow(); dr["id"] = index.ToString(); dr["item"] = "item" + index.ToString(); //给dt001添加当前行 dt001.Rows.Add(dr); } DataTable dt002 = ds.Tables.Add("table002"); dt002.Columns.Add("id"); dt002.Columns.Add("name"); for (int index = 1; index <= 5; index++) { DataRow dr = dt002.NewRow(); dr["id"] = index.ToString(); dr["name"] = "name" + index.ToString(); dt002.Rows.Add(dr); } GridView1.DataSource = ds.Tables["table001"]; GridView2.DataSource = ds.Tables["table002"]; GridView1.DataBind(); GridView2.DataBind(); //遍历DataSet的DataTable集合 Response.Write("DataSetName:" + ds.DataSetName.ToString() + "<br />"); Response.Write("DataSet中共有" + ds.Tables.Count.ToString() + "个表,名称如下:<br />"); foreach (DataTable table in ds.Tables) { Response.Write(table.TableName + "<br />"); } }
(3)然后按Ctrl+F5组合键,运行显示效果如图4-31所示。
4.5.4 删除DataSet中的DataTable
当DataSet中的某个DataTable不用了,可以使用下面语法移除。
ds.Tables.Remove(DataTableName); //或者 ds.Tables.RemoveAt(Index);
例如要删除上述DataSet中的表table002,就可以使用下面语法完成。
ds.Tables.Remove("table002"); //或者 ds.Tables.RemoveAt(1);