一、引言
ASP.NET 2.0新增加了不少新的功能和控件。其中,在数据的缓存功能上有了很大的改变。众所周知,数据的缓存功能是十分重要的,我们可以把一些在相对一段时间内不发生改变的数据放在缓存中,这样,就不必要每次去读取数据库,当下次再需要这些数据时,可以直接从缓存中取得,大大增强了效率。
在asp.net 早期版本(1.1) 中,已经比较好地实现了数据的缓存功能,但有一个小问题,那就是如果数据库中的数据发生了变化,缓存不能在指定的时间内更新,而必须等到缓存失效。比如,在网页中,如果你对商品的一些详细信息,如商品所在的门类使用了页面缓存,那么假如在后台修改了这些信息,用户不会马上看到这些信息,而要延迟一些时间(譬如,页面的缓存到期了)才看到。在某些应用场合,如果你要做到对于数据库的任何更新,都能马上可以在缓存的变化生效的话,在asp.net 1.1中则是比较难实现的,而在asp.net 2.0中,则可以很方便地实现该功能。
二、编码前的准备工作
针对SqlServer2005(内置支持SQL数据缓存依赖,内置通知传递服务,能够提供更小粒度的数据更改监测,使用和配置简单。).
1、检测是否已经启用Service Broker
执行Select databasepropertyex('db Name', 'IsBrokerEnabled') 结果:'1' : broker is enabled,'0' :broker is not enabled
2、启用Service Broker(让相应的数据库启用监听服务,以便支持SqlDependency特性。如果步骤1中的sql语句结果是1,可以跳过步骤2)
ALTER DATABASE databasename SET ENABLE_BROKER
注意:有时该sql语句执行的时间会很长,那么请把数据库连接断开(或干脆把Microsoft SQL Server Management关闭重新打开)重新启动连接,执行该 语句只需数秒钟。
原因可能是:该命令可能需要产生排他锁,然而,当数据库处于连接状态时就不能产生排他锁,所以就一直等待最后挂起。
三、编写代码
(1)在实现基于服务的SQL数据缓存依赖过程中,需要显式调用SqlDependency.Start来启动接受依赖项更改通知的侦听器,调用SqlDependency.Stop关闭。
在Global.asax文件中
void Application_Start(object sender, EventArgs e) { //在应用程序启动时运行的代码 string connStr = BalloonShopConfiguration.DbConnectionString; System.Data.SqlClient.SqlDependency.Start(connStr); } void Application_End(object sender, EventArgs e) { //在应用程序关闭时运行的代码 string connStr = BalloonShopConfiguration.DbConnectionString; System.Data.SqlClient.SqlDependency.Stop(connStr); }
(2)应用程序数据缓存中编写如下代码:
public class CatalogAccessUseSqlCache { public static DataTable GetDepartments() { string connStr = BalloonShopConfiguration.DbConnectionString; SqlConnection conn=null; try { conn = new SqlConnection(connStr); SqlCommand comm = new SqlCommand(); comm.Connection = conn; SqlCacheDependency dep = new SqlCacheDependency(comm); comm.CommandType = CommandType.Text; comm.CommandText = "SELECT DepartmentID,Name,Description FROM dbo.Department"; SqlDataAdapter adapter = new SqlDataAdapter(comm); conn.Open(); DataTable dt=new DataTable(); adapter.Fill(dt); System.Web.HttpContext.Current.Cache.Add("GetDepartments", dt, dep, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null); return dt; } catch(Exception ex) { Utilities.LogError(ex); throw ex; } finally { conn.Close(); } } }private void BindGrid() { if (HttpContext.Current.Cache["GetDepartments"] == null) { //Get a DataTable object containing the catalog departments //grid.DataSource = CatalogAccess.GetDepartments(); list.DataSource = CatalogAccessUseSqlCache.GetDepartments(); } else { list.DataSource = (System.Data.DataTable)HttpContext.Current.Cache["GetDepartments"]; } //Bind the data bound controls to the data source list.DataBind(); }
(3)与 sqlCommand 参数关联的 SQL 语句必须包括以下内容
a、必须设置完全限定名称的数据表。即表名前面需要加所有者,如dbo.Department
b、必须明确设置所访问数据库列名称,不能使用通配符(“*”)。
例如,不能使用 "select * from Department",而必须使用 "DepartmentID,Name,Description FROM dbo.Department"。
c、必须保证不是聚合函数。如COUNT、MAX等
经过如上的几个步骤,就基本上完成了sql依赖缓存的代码编写。
四、相关知识点的介绍(老生常谈的内容,不过很容易忘记)
(1)SqlCacheDependency的初始化
构造函数:public SqlCacheDependency (SqlCommand sqlCmd)。
(2)System.Web.Caching.Cache Insert和Add区别
有关Add与Insert方法的详细信息见MSDN:
http://msdn.microsoft.com/zh-cn/library/system.web.caching.cache.add(v=VS.80).aspxhttp://msdn.microsoft.com/zh-cn/library/system.web.caching.cache.insert(v=VS.80).aspx
2者的一些区别如下:a、Insert方法支持5种重载,使用灵活,而Add方法必须提供7个参数;b、Add方法可以返回缓存项的数据对象,Insert 返回Void;c、添加重复缓存情况下,Insert会替换该项,而Add方法会报错。
五、小结
本篇讲解了一些关于Asp.Net数据缓存的一些基本知识,更多的知识点与注意点还需实际使用时注意.