(本帖在版工的旧 Blog 中,发表日期为 2007/06/09)
知名计算器图书作家 - 章立民老师,几年前有两篇文章,提到 DataSource 控件的 DataSourceMode 属性:
立民讲堂
ASP.NET 2.0 – 善用DataSourceMode属性 :
http://www.cnblogs.com/liminzhang/archive/2006/12/18/595332.html
ASP.NET 2.0 - 选用DataSet或DataReader :
http://www.cnblogs.com/liminzhang/archive/2006/12/26/603991.html
在 ASP.NET 2.0 页面中的控件,若要展示数据库的数据,或要写入数据库时,我们可从 VS 2005 的「工具箱」中点选 DataSource 控件,用鼠标拖曳、轻松地建立数据库联机。但在 SqlDataSource 控件中,预设使用的联机方式,为具有「离线存取」功能的 DataSet 对象;但就如章老师讲的,不需要进行「排序、筛选与分页」时,根本没必要浪费内存,反而还牺牲了一些程序性能 (performance)。
因此,若您的 ASP.NET 页面使用了 SqlDataSource 作为控件的数据来源,应视需求,再手动调整 DataSourceMode 属性。若您的 SqlDataSource 只是当作 Label、DropDownList、ListBox、…等控件的数据绑定,纯粹用来「显示」数据,应如下图 1 所示,在 VS 2005 中,在 SqlDataSource 的「属性」窗口中,将 DataSourceMode 属性改为「DataReader」(预设为 DataSet)。此举不但可提升程序存取速度,亦可节省 server 上因 DataSet 造成非必要的内存消耗。但若您的 SqlDataSource,是用来当作 GridView 控件的数据来源,且 GridView 需要:分页、排序、筛选 (非指 T-SQL 语句的 WHERE 或 JOIN...ON,而是指 DataSet 中的 DataTable 对象、RowFilter 属性,对已从数据库中捞取出来的数据再进行筛选) 这些功能,即不用再手动调整 DataSourceMode 属性,直接使用默认的 DataSet 即可。
图 1 将 SqlDataSource 的 DataSourceMode 属性,从默认的 DataSet 改成 DataReader
在 ADO.NET 中,DataReader 可「单向 (顺向)、只读」地读取数据库中的数据,优点是读取速度快、不须耗用 server 额外的内存;DataSet 则是一种可让使用者「离线」存取数据的模式,数据都会暂存至内存中,有如可离线操作的数据库 (大家可以先猜看看,是存在 client-side 还是 server-side 的内存)。
DataSet 是从 ADO.NET 1.x 开始,微软即大力推广的「离线数据库存取模式」,是为了改善早年 ADO 必须持续保持联机,但在有大量用户同时上线时,常造成 web 应用程序运作性能上的致命伤。如今透过 ADO.NET + DataSet 的离线模式,当程序透过 ADO.NET 取得数据之后,会立即和数据库断线,以释放资源,但使用者仍可透过应用程序,去存取内存中的数据库 (DataSet);并在必要的时候 (例如要把修改过的数据回写到数据库),才再重新建立联机回写,然后再断线。这样的运作方式,能有效地节省数据库联机资源,改善过去 ASP 网站为人垢病,遇到大量使用者同时存取时,性能不彰的缺点。
「DataSet 离线机制」若用来开发同时间有大量用户存取的网站时,也可减少与 server 往返沟通的次数,降低网络的流量;而「DataReader 实时联机机制」,在一般情况下的执行性能反而较好,因为 DataReader 在「读取」数据 (SQL SELECT) 的速度上,一定会比 DataSet 快。
至于 ADO.NET 的离线机制,其 DataSet 对象到底存储在何处呢?就一些前辈们的使用经验而言,如果是一个 Windows Form 程序,其所建立的 DataSet 对象会储存在客户端的计算机内存中,它与后端 server 的数据来源是完全中断连接的;但如果是一个 Web Form 的 ASP.NET 网页,则所建立的 DataSet 对象,会储存在 IIS server 的内存中。
此外,在 ADO.NET 2.0 中,DataTable 已可单独存在,不必再依附于 DataSet 中,因此您也可视情况,以 DataTable 替代 DataSet 来撷取、操控数据,如此亦可耗用较少的系统资源。
虽然根据官方的说法,DataReader 的特性为只读、不允许使用者修改数据库里的数据,但根据版工自行撰写的简单范例测试,用 DataReader 做绑定的 TextBox,使用者所输入的数据,仍可再写入 SQL Server 2005 中。关于这点,根据台湾网络上其它人的看法,DataSourceMode 指的,应该只是 SelectCommand (亦即以 SELECT 撷取数据的 SQL statement) 取回数据时,所使用的一种「Mode」而已,和 SqlDataSource 的其它指令无关;其它指令使用的 SqlConnection 和 SqlCommand 是另外打开的,应该与 SelectCommand 无关。有兴趣测试的网友,可由本帖下方,下载此一测试示例。示例中并另外展示,如何用 Validator (验证控件) 去验证 DropDownList 控件,要求用户至少要在 DropDownList 里选择一项,才可按下按钮将 Form 数据 submit。
https://files.cnblogs.com/WizardWu/070609.zip
(本范例是连接 SQL Server 的 Northwind 数据库,联机账号为 sa,密码为 test。若密码与您数据库的设定不同,请自行修改 Web.config 档案)