首先,Pet Shop中应用了ASP.Net 2.0中新增加的SqlCacheDependency能力,通过配置文件的设置,Framwork会自动定时轮询数据库中的一个监视表,而被监视表上有 一个触发器,在发生Insert、Update、Delete操作的时候就会改变监视表中ChangeID的值。这样一来,每当ChangeID发生了变 化,SqlCacheDependency就会自动使得Cache失效,那么下一次请求到达服务器时,程序将直接从数据库中提取出最新的数据并重新插入 Cache中,于是Cache的过期就不必手动编码操作了!
但是仔细查看代码会发现,Web项目的App_Code文件夹下有一系列的DataProxy类,里面都是静态方法,通过代码不难看出,这些类是用 于数据访问的,即首先判断是否所需数据已经存在于缓存中,若有,则直接访问缓存,若无,则访问数据库返回填充好的数据实体对象并缓存起来,插入缓存时,正 使用了SqlCacheDependency机制。
可是如果你在整个Solution里面搜索相应的DataProxy类,你会一无所获!难道这些代码只是说放在那里而已,难道它们也只是为了显示一下自己的新锤子?
一开始我也百思不得其解,后来看到页面里面的代码时,猛地恍然大悟。原来Pet Shop中实现了两套缓存方式,一种是类似于DataProxy的那种传统方法,将数据实体缓存起来,另一种则是结合了ASP.NET的页面缓存机制来实现的。
查看ProductsControl.ascx文件你会在头部发现一个伪指令声明:<%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %>第一个参数是定义了控件的过期时间,第二个参数则定义了区分缓存的参数(2.0新特性),然后查看 ProductsControl.ascx.cs文件你会发现在protected void PageChanged方法中有productsList.DataSource = product.GetProductsByCategory(categoryKey);语句,这个语句是直接使用DAL访问数据库,(没有先查询缓 存,这也是很多人百思不得其解的地方)但是关键不在这里,在protected void Page_Load方法中有一行语句this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();这条语句的作用就在于将SqlCacheDependency同样应 用于页面的缓存过期。
这样一来,缓存的就不光是数据实体类而已,而是整个控件被Render出来后的html!这样一来还省去了每次访问页面时的Render操作,效率显然比光缓存实体类高得多!
ps: 如果你想使用光缓存实体类的方式,那么请删除ascx文件中的OutputCache声明,注释掉page_load中的过期策略语句,然后将 productsList.DataSource = product.GetProductsByCategory(categoryKey);改为productsList.DataSource = ProductDataProxy.GetProductsByCategory(categoryKey);其他页面同理操作。
结论是PetShop实现了两种缓存方式,但是默认它使用了更高效的那种。可惜又让初学者看不懂了,22个项目,残念ing...