文字显示结果
组合搜索  计算机图书分类目录
 
所在位置: 图书 -> 在线试读 -> ASP.NET 3.5网站开发全程推演与视频精讲 
                 

第9章 使用ADO.NET操纵数据

9.6 脱机模式数据操纵

上一节介绍了如何执行直接数据操纵。本节介绍如何执行脱机数据操纵。

9.6.1  脱机模式数据操作流程

从前面的介绍可知,ADO.NET支持直接数据操纵和脱机数据操纵。这两种模式都有相应的类支持。连接模式类用于从底层数据源提取和更新数据,它包括ConnectionCommandDataReaderDataAdapter。每个数据提供程序负责实现特定连接模式类。脱机模式类可以对使用连接类提取的离线数据进行访问和操纵,然后使用连接模式类同底层数据源同步。脱机模式类包括DataSetDataTableDataColumnDataRowDataViewDataRelationConstraint

当在脱机模式下访问数据时,需要使用DataSet对象将数据的一个副本保存在内存中。尽可能保持同数据库的连接,以提取所需要的数据,将其保持到DataSet对象中,然后断开连接。相对于DataReader的直接数据访问,使用DataSet将数据保持在内存中有许多好处,例如:

l        某些时候,处理数据需要耗费大量的时间。如果将数据首先提取到内存中,只需要让连接保持相对较少的时间,从而能够将连接提供给其他需要的地方使用。

l        如果需要将ASP.NET数据绑定到一个Web控件,虽然可以使用DataReader,但在某些场合下,使用DataSet方法更为直观。

l        在处理数据时,可能需要向前或者向后导航数据。使用DataReader无法实现,它只能朝一个方向,也就是向前导航数据。

l        如果希望从一个表导航到另一个表,可以使用DataSet存储几个表的信息,甚至可以定义表之间的关系,从而能够更加高效地浏览它们。

如果希望从数据库中提取记录,然后存放在DataSet中,需要使用DataAdapter对象。每个DataAdapter对象包括4个命令:SelectCommandInsertCommandUpdateCommandDeleteCommand。使得使用单个DataAdapter对象,可以执行多个任务。构造函数提供的Command对象自动赋予DataAdapter.SelectCommand属性。图9-14显示了使用脱机模式执行数据操纵的基本流程。

 

9-14  脱机模式下的数据操纵流程

针对SQL Server数据提供程序,DataAdapter也提供了特定实现SqlDataAdapter,下面给出了其常用属性,如表9-7所示。

 

9-7  SqlDataAdapter的常用属性

名称

说明

AcceptChangesDuringFill

获取或设置一个值,该值指示在任何 Fill 操作过程中,再将 AcceptChanges 添加到 DataTable 之后是否在 DataRow 上调用它

AcceptChangesDuringUpdate

获取或设置在 Update 期间是否调用 AcceptChanges

ContinueUpdateOnError

获取或设置一个值,该值指定在行更新过程中遇到错误时是否生成异常

DeleteCommand

获取或设置一个 Transact-SQL 语句或存储过程,以从数据集删除记录

InsertCommand

获取或设置一个 Transact-SQL 语句或存储过程,以在数据源中插入新记录

SelectCommand

获取或设置一个 Transact-SQL 语句或存储过程,用于在数据源中选择记录

TableMappings

获取一个集合,它提供源表和 DataTable 之间的主映射

UpdateBatchSize

获取或设置一个值,该值启用或禁用批处理支持,并且指定可在一次批处理中执行的命令的数量

UpdateCommand

获取或设置一个 Transact-SQL 语句或存储过程,用于更新数据源中的记录

SqlDataAdapter最常用的方法是其Fill()方法,具有多种重载形式,如表9-8所示。

9-8  SqlDataAdapter.Fill()方法的重载形式

名称

说明

Fill(DataSet)

DataSet 中添加或刷新行

Fill(DataTable)

DataSet 的指定范围中添加或刷新行,以与使用 DataTable 名称的数据源中的行匹配

Fill(DataSet, String)

DataSet 中添加或刷新行,以匹配使用 DataSet DataTable 名称的数据源中的行

Fill(DataTable, IDataReader)

DataTable 中添加或刷新行,以与使用 DataTable 名称和指定的 IDataReader 的数据源中的行匹配

Fill(DataTable, IDbCommand, CommandBehavior)

DataTable 中添加或刷新行,以与使用指定的 DataTableIDbCommand CommandBehavior 的数据源中的行匹配

Fill(Int32, Int32, array<DataTable>[]()[])

DataTable 中添加或刷新行,以与从指定的记录开始一直检索到指定的最大数目的记录的数据源中的行匹配

Fill(DataSet, Int32, Int32, String)

DataSet 的指定范围中添加或刷新行,以匹配使用 DataSet DataTable 名称的数据源中的行

Fill(array<DataTable>[]()[], IDataReader, Int32, Int32)

DataTable 对象集合的指定范围中添加或刷新行,以与数据源中的行匹配

Fill(DataSet, String, IDataReader, Int32, Int32)

DataSet 的指定范围中添加或刷新行,以匹配使用 DataSet DataTable 名称的数据源中的行

Fill(array<DataTable>[]()[], Int32, Int32, IDbCommand, CommandBehavior)

DataSet 的指定范围中添加或刷新行,以匹配使用 DataSet DataTable 名称的数据源中的行

Fill(DataSet, Int32, Int32, String, IDbCommand, CommandBehavior)

使用 DataSet 和源表名称、命令字符串及命令行为,在 DataSet 的指定范围中添加或刷新某些行,以使它们与数据源中对应的行相一致

在脱机模式中,DataSet是核心对象,它是从数据源中检索到的数据在内存中的缓存。DataSet 由一组 DataTable 对象组成,可使这些对象与 DataRelation 对象互相关联。还可通过使用 UniqueConstraint ForeignKeyConstraint 对象在DataSet 中实施数据完整性。

l         在填充DataSet时,DataAdapter使用DataReader。因此,使用DataAdapter取代DataSet提升的性能表现为节省了DataSet占用内存和填充DataSet需要的循环。一般来说,此性能提升只是象征性的,因此,设计决策应以所需功能为基础。

l         如果想用服务器上的更新值刷新DataSet中的值,就使用DataAdapter.Fill。如果有在DataTable上定义的主键,DataAdapter.Fill会根据主键进行新行匹配,并且当更改到现有行时应用服务器上的值。即使刷新之前修改了这些数据,刷新行的RowState仍被设置为Unchanged

注意如果没有为DataTable定义主键,DataAdapter.Fill就用可能重复的主键值添加新行。

 

DataSet中查询与特定条件相匹配的行时,可以利用基于索引的查找提高搜索性能。当将PrimaryKey值赋给DataTable时,会创建一个索引。当给DataTable创建DataView时,也会创建一个索引。下面是一些利用基于索引进行查找的技巧:

l         如果对组成DataTablePrimaryKey的列进行查询,要使用DataTable.Rows.Find而不是DataTable.Select

l         对于涉及到非主键列的查询,可以使用DataView为数据的多个查询提高性能。当将排序顺序应用到DataView时,就会建立一个搜索时使用的索引。DataView公开FindFindRows方法,以便查询基础DataTable中的数据。

l         如果不需要表的排序视图,仍可以通过为DataTable创建DataView来利用基于索引的查找。

注意:只有对数据执行多个查询操作时,才会带来好处。如果只执行单一查询,创建索引所需要的处理就会降低使用索引所带来的性能提升。

9.6.2  演练:使用脱机模式数据查询图书列表信息

下面通过一个示例,来介绍如何在ASP.NET应用中执行脱机模式的数据查询。

实现对网上书店应用订单的脱机模式查询。

 

我们可以按照如下步骤来加以实现。

<DIV>

01

</DIV>
创建一个ASP.NET Web项目。

<DIV>

02

</DIV>
创建数据查询页并添加控件。

<DIV>

03

</DIV>
编写后台处理代码,执行脱机数据查询。

<DIV>

04

</DIV>
编译并执行。

下面详细介绍上述步骤。

创建一个ASP.NET Web项目
<DIV>

01

</DIV>
,命名为“DisconnectedDataApp”。

<DIV>

02

</DIV>
Default.aspx窗体页面中添加一个GridView控件,其设计视图如图9-15所示。

<DIV>

03

</DIV>
编写窗体页面的后台处理代码并执行数据查询如下所示:

【程序9-3】光盘\code\09 \DisconnectedDataApp\Default.aspx.cs

01        using System;

02        using System.Collections.Generic;

03        using System.Linq;

04        using System.Web;

05        using System.Web.UI;

06        using System.Web.UI.WebControls;

07        using System.Data.SqlClient;

08        using System.Data;

09         

10         

11        namespace DisconnectedDataApp

12        {

13            public partial class _Default : System.Web.UI.Page

14            {

15                protected void Page_Load(object sender, EventArgs e)

16                {

17                    string constr = GetConnectionString();

18                    DataSet ds = queryData(constr);

19                    GridView1.DataSource = ds;

20                    GridView1.DataBind();

21                }

22                private static DataSet queryData(string connectionString)

23                {

24                    //Create a SqlConnection to the Northwind database.

25                    using (SqlConnection connection =

26                               new SqlConnection(connectionString))

27                    {

28                        //创建sqlDataAdapter对象

29                        SqlDataAdapter adapter = new SqlDataAdapter();

30                        adapter.TableMappings.Add("Table", "Book");

31                        // 打开连接

32                        connection.Open();

33                        Console.WriteLine("The SqlConnection is open.");

34         

35                        // 创建SqlCommand,提取数据

36                        SqlCommand command = new SqlCommand(

37                            "SELECT BookName, Press FROM dbo.Book;",

38                            connection);

39                        command.CommandType = CommandType.Text;

40         

41                        // 设置SqlDataAdapter SelectCommand属性

42                        adapter.SelectCommand = command;

43                        // 填充DataSet

44                        DataSet dataSet = new DataSet("Book");

45                        adapter.Fill(dataSet);

46                        // 关闭连接

47                        connection.Close();

48                        return dataSet;

49                    }

50                }

51                static private string GetConnectionString()

52                {

53                    return "Data Source=(local);Initial Catalog=BookShopOnlineDB;"

54                        + "Integrated Security=SSPI";

55                }

56            }

57        }

<DIV>

04

</DIV>
编译并执行,可以看到如图9-16所示的执行结果。

  9-16  执行结果

l         执行脱机模式数据查询,首先创建了SqlAdapter对象,设置其SelectCommand属性,然后使用DataSet将结果保存下来。在此,为了显示数据,我们用到了数据绑定,读者在此主要理解如何执行脱机模式数据查询,对于数据绑定的内容,将在下一节进行详细分析。

l         对于数据的插入、更新和删除操作,通过设置SqlAdapter的对应Command对象,然后调用Update()方法应用更新即可。

 

ADO.NET可以显式控制从数据源中返回什么样的数据,以及在本地DataSet中缓存多少数据。对查询结果的分页没有唯一的答案,但下面有一些在设计应用程序时应该考虑的技巧:

l         避免使用带有startRecordmaxRecords值的DataAdapter.Fill重载。当以这种方式填充DataSet时,只有maxRecords参数(从startRecord参数标识的记录开始)指定的记录数量用于填充DataSet,但无论如何总是返回完整的查询。这就会引起不必要的处理,读取不需要的记录;而且为了返回附加记录,会耗尽不必要的服务器资源。

l         用于每次只返回一页记录的技术是创建SQL语句,将Where子句以及Order BY子句和TOP谓词组合起来。此技术取决于存在一种可唯一标识每一行的办法。当浏览下一页记录时,修改Where子句使之包含所有唯一标识符大于当前页最后一个唯一标识符的记录。当浏览上一页记录时,修改Where子句使之返回所有唯一标识符小于当前页第一个唯一标识符的记录。两种查询都只返回记录的TOP页。当浏览上一页时,需要以降序为结果排序。这将有效地返回查询的最后一页(如果需要,显示之前也许要重新排序结果)。

l         另一项每次只返回一页记录的技术是创建SQL语句,将TOP谓词和嵌入式Select语句的使用结合在一起。此技术并不依赖于存在一种可唯一标识每一行的办法。使用这项技术的第一步是将所需页的数量与页大小相乘。然后将结果传递给SQL QueryTOP谓词,该查询以升序排列。再将此查询嵌入到另一个查询中,后者从降序排列的嵌入式查询结果中选择TOP页大小。实质上,返回的是嵌入式查询的最后一页。

l         如果数据不经常变动,可以在本地DataSet中维护一个记录缓存,以此提高性能。例如,可以在本地DataSet中存储10页有用的数据,并且只有当用户浏览超出缓存第一页和最后一页时,才从数据源中查询新数据。

 
 
  上一页 返回 下一页  
 
Copyright © 2010 TianMei Technology All rights reserved. To comment on this site
  辽B-2-4-20100065