高效DataGrid控件解决方案(原创)
SmartDataGrid解决方案
1. 提出问题
在过去的几个ASP.NET项目中,我们在很多情况下使用了DataGrid控件,或者基于DataGrid构造的控件。DataGrid控件是非常便捷的,程序员在服务器端编写代码,在从服务器查询出数据(比如DataSet,DataView,DataTable等格式)后,可以直接绑定到DataGrid,使得程序员有更多时间和精力处理比较复杂的业务逻辑。然而,DataGrid消耗的服务器端性能太大,令我们的客户非常头疼。一台高性能的服务器,在只有上百个用户的情况下,速度依然很慢,而且这曾造成我们的客户页面崩溃。追其根源,DataGrid在每一次得分页,排序,选中行或者使用模板列中服务器控件时等操作时,都会刷新整个页面,并且需要重新绑定。
该怎样根据客户的实际情况,构造令客户满意的DataGrid控件呢?下面我们先来从功能角度出发,来逐步探讨DataGrid。
2. 分析问题
我们使用DataGrid最重要的原因是用来表达数据,DataGrid表达的数据是一个完整的表的概念。对于软件操作员,也就是我们的客户,最需要的是能非常方便的查询和操作恰当的数据。比如为数据排序,拖动列。最常见的功能有分页,排序,选中行,滚动条四中。其中分页的功能最为重要,也最影响性能。
在参考了一些其它优秀软件公司,优秀的编程人员的意见后,我们将就DataGrid分页
的问题上,提出如下四种参考方案:
l 第一种方案:直接绑定方式。每次分页,从数据库重新提取所需数据,然后绑定数据。
优点:每次返回的数据较少。
缺点:访问数据库的次数太多,而且select语句需要特殊处理。
适用场合:适用于数据表中数据量比较少。一个数据表中的数据总量如果只有几M,即使最差的分页算法也不会让人感觉很慢,不会有性能的问题。
l
第二种方案,把数据保存在session中,然后每次分页时从Session绑定到DataGrid
优点:编程简单,数据库访问次数少
缺点:速度较慢,数据量大时占用内存太大
l 第三种方案,将数据保存在页面缓存中,然后每次分页时从cache绑定到DataGrid
优点:session中存的数据是单会话独享.cache是应用程序级共享的.因此一个用户在查询数据出来后,其它的用户访问起来不用从数据库取数据,直接从cache中取数据,比较高效。
缺点:如果是动态数据,cache就没有意义了,小批量数据也没有cache的必要,如果是大批量数据,缓存太消耗资源。
适用场合:固定不变的数据。
l 第四种方案,将数据保存在静态变量中
优点:静态变量的存取效率比Application 和Session 以及Cache 快10倍以上。
缺点:同上面cache
适用场合:同上面cache
综合以上4种方案,我们得出这样的结论,对于量少且变化不大的数据,可以使用静态变量的方式来储存数据,直接使用 DataGrid控件,但是对于大数据量的或者经常变化的数据,这四中方案都是不适用的,因此,我们就需要重新提出另外的解决方案了。
3. 解决问题
假设我是客户,我希望看到这样一个Table,在我鼠标翻页时,我不希望看到页面刷新闪烁,我也不希望等待很久,我希望能像操作常规的表一样,能用CTRL或者SHIFT键复选,能上下排序,能回车跳转到任意我想去页面,等等。。我希望能有一个敏捷的DataGrid。下面我称为SmartDataGrid。
为了这样一个SmartDataGrid,我们需要突破传统的约束,不再基于DataGrid做文章,彻底摆脱DataGrid控件带来的干扰和困惑,有了这个线索,我们接下来逐步探讨。
l 在上一步的思路中,首先阻碍我们的是,怎样能无刷新取得数据?我们可以利用回滚的基本原理,客户端试用XMLHTTP来实现无刷新。
l 接着,无刷新实现的基础上,我们有了新的问题:怎样的流程能减少客户端服务器端的交互,又以什么样的格式来传递数据呢?我们怎样为SmartDataGrid分页呢?
即使我们看不到刷新,取数据的操作只能在服务器端进行,在服务器端返回的数据的格式DataSet。这样我们可以使用XML格式来传递数据。
l 现在,我们还需要考虑分页的问题。假定一个变量M,M代表用户希望一次看到的记录的条数,为了实现分页,我们需要知道数据库中总的记录条数N,这样我们需要从服务器端取一次数据,返回客户端这个N值,在知道这个值之后,客户端才可以用户页数计算出查询出来的记录得起始位置,才可以继续从服务器端取得相应的数据。这样,过程就比较清晰了。整个流程如下:
n 首先,定义基本参数:表名,字段,每页显示条数,和当前页数。
n 客户端将表名,字段,参数传递到服务器端,取出数据库的总记录条数。
n 服务器端返回总记录条数给客户端。
n 客户端根据参数每页显示条数,和当前页数,计算取出第几条数据到第几条数据,这样的一个起始与结束位置传递给服务器端。
n 服务器端根据这样的参数取数据(其中,通过ROWNUM(ORACLE)或者TOP N(SQLSERVER) ,我们可以快速取得数据,更好可以采用存储过程来实现),以XML的格式发送给客户端,在客户端实现绑定。
l 这样分页的速度已经令人比较满意了。但是怎样解决选中行和排序还是一个小小难题。为了不再动用数据库,希望能在客户端实现分页和选中行,这样问题就简单很多,我使用了HTC与VBSCRIPT来实现,具体过程,不再赘述。