因为这里我们使用了缓存,所以有必要讨论一下缓存。我们知道缓存共有三种,一种是OutputCache,一种是基于数据源控件的数据缓存,一种是基于 System.Web.Caching.Cache 类的对象缓存。在这三种缓存中,OutputCache和 数据缓存 又可以应用SqlCacheDependency缓存过期策略,SqlCacheDependency说简单些就是当数据库的数据发生改变的时候使依赖于此数据库(表)的缓存自动过期,SqlCacheDependency又分为Sql Server2000的基于轮询(Polling)的拉机制,和Sql Server2005 基于通知(Notification)的推机制两种不同策略。而应用System.Web.Caching.Cache时不能应用SqlCacheDependency过期策略,只能应用基于某个文件改变或其他Cache项目改变的过期策略。
NOTE:Sql Server2000 的轮询(Polling)机制意思是说Asp.Net进程每隔一段时间就对数据库进程进行一此访问,因为间隔时间是固定的,所以叫轮询(访问时间以毫秒为单位,可以在Web.Config里设置)。当某次轮询时发现与上一次访问时的数据不一样,那么就立刻使依赖于此数据的缓存过期。Sql Server2005 的通知(Notification)机制是说Asp.Net只管做自己的事情,不对数据库进程进行询问,而当数据库的数据发生变动时,Sql Server 2005进程主动通知Asp.Net进程,告诉它数据发生了改变,然后Asp.Net让缓存过期。由此可见,使用Sql Server2005 的通知机制效率要高得多。
如何开启SqlDependency本文不讲述了,可以查阅相关书籍。
当我提到缓存的时候你可能会觉得对于基于业务对象的筛选我使用了缓存,而对于拼装SQL的方式我没有,这样去比较它们显得不公平,那么我现在列张表,对于它们各自应用缓存时的表现做一个对比(SqlDependency使用SqlServer 2000的轮询机制):
缓存名称 | 基于拼装SQL筛选 | 基于业务对象筛选 |
OutputCache VaryByParam="*" Duration="600" | 当下拉框的选项较少的时候比较有意义,在缓存有效期内,不会对数据库进行访问。但当选项较多时,会对较多页进行缓存,第一次访问时仍要访问数据库,缓存多个页面结果,效果不够好。数据库数据改动时,缓存不会过期。 | 没有意义,因为业务对象已经是自缓存读出。数据库数据改动时,缓存不过期。 |
OutputCache VaryByParam="*" Duration="999999" SqlDependency="Northwind:Orders" | 与上同,但是当数据变动时会使缓存过期。 | 没有意义,当数据库数据改动时,会使页面缓存过期,页面缓存要求重新加载数据,但是重新加载的数据依然来自缓存中的对象。结果是即使数据库发生改变,页面显示结果依然没有改变。 |
ObjectDataSource EnableCaching="true" CacheDuration="600" | 在缓存有效时间内,下拉列表的功能失效。因为在Cache有效期内,GridView的DataBind()方法不会使数据源重新读取数据(数据源不会触发Selecting事件),换言之,数据源不会调用GetList(query)方法,因此列表功能失效。 | 效果与拼装Sql方法一样,列表失效。 |
ObjectDataSource EnableCaching="true" CacheDuration=" infinite" SqlDependency="Northwind:Orders" | 列表失效,与上面效果相同,区别仅仅是在数据库改动时缓存过期(在失效后的第一次访问,列表有效)。 | 列表失效,与拼装Sql方法一样。区别是SqlDependency也失效,因为在数据库数据变动时,数据缓存过期,数据源重新读数据,但是数据依然来自于缓存。 |
Catch Insert("fullList", List<Order>) | 基本不可实施(对每次返回结果进行缓存,效果基本等同于全部返回,且非常麻烦) | 本文对象即是应用此方法缓存。 |
很