对与缓存来讲,文件缓存最为有空,因为无论从技术上还是安全性来说,都是最好的,本人从了解到有空研究这个东东,现在将心得写出来。
一, 以前本人学习ASP。NET的时候有本书上是这样介绍文件依赖的(主要是针对数据库)。怎么样才能将数据库里面数据的更新和数据库之外的文件打到同步更新呢,这个是很麻烦的问题,很多人都知道应该是写个触发器,可是具体的怎样达到同步确实个问题,幸运的是,sql2000或者sql7.0以上的版本,sql2005都具有这样的一个存储过程. sp_makewebtask.作用么,自己看存储过程本身,就会有发现,make_web也就是说,调用这个存储过程的目的是为了在相应的目录下面产生web文件,也就是html。详细的用法在下面:
CREATE TRIGGER WriteCacheDepFile ON [dbo].[user]
FOR INSERT, UPDATE, DELETE
AS
Exec sp_makewebtask path,sql
它具有两个参数,path,是之您的依赖文件的绝对路径,sql之的的t_sql语句。需要说明的是,这里的sql语句的输出结果将会反映到path目录下面的文件里面。
好了,第一步已经完成了,那么我们来继续写相应asp.net部分的内容,为了读者能明白,笔者先将最简单的(笔者以前用的)代码作为解释:
protected static void RefreshCache(string key, object item, System.Web.Caching.CacheItemRemovedReason reason)
{
string mycon=ConfigurationManager.AppSettings["myconnection"];
SqlConnection myconnection=new SqlConnection(mycon);
SqlDataAdapter dp = new SqlDataAdapter("select * from [user]", myconnection);
DataSet ds = new DataSet();
dp.Fill(ds, "[user]");
CacheItemRemovedCallback onRemove = new CacheItemRemovedCallback(RefreshCache);
string defile = System.Configuration.ConfigurationManager.AppSettings["dependencyFile"].ToString();
HttpContext.Current.Cache.Insert("[user]", ds, new CacheDependency(defile), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.High, onRemove);
}
CacheItemRemovedCallback委托的说明:
其实笔者认为c#的好处和精髓所在就是有了委托机制的实现,这个很有用,我在这里就不多说了,让我门继续上面的课程。
这个委托的作用说白了,就是在与文件依赖的过程中,如果文件发生了变化,调用响应的枚举来响应时间,可以拿触发器来相比。
CacheDependency类,其作用是取得依赖的实际意义,包括文件依赖的绝对地址等等。
具体的使用方法请参见msdn。下面是调用说明:
if (Cache["[user]"] == null)
{
RefreshCache(null, null, 0);
}
else
{
Response.Write("conghuancunzhongduqu");
DataSet ds;
ds =(DataSet) Cache["[user]"] ;
DataGrid1.DataSource = ds.Tables["[user]"].DefaultView;
this.DataGrid1.DataBind();
}
可是上面的发放虽然有用,可笔者使用3层结构的开发的时候就来了不少麻烦,因为关键性的方法是具有参数的,这个很不好般,所以就有了下面的方法
static bool itemRemoved = false;
static CacheItemRemovedReason reason;
CacheItemRemovedCallback onRemove = null;
protected void Page_Load(object sender, EventArgs e)
{
bind();
}
public void RemovedCallback(String k, Object v, CacheItemRemovedReason r)
{
itemRemoved = true;
reason = r;
}
public void AddItemToCache()
{
CacheDependency dep = new CacheDependency("D:\\ASP.NET工程\\sqlcache\\cache.htm",DateTime.Now);
string sqlcon = ConfigurationManager.AppSettings["myconnection"].ToString();
SqlConnection con = new SqlConnection(sqlcon);
DataSet ds = new DataSet();
string sql = "select * from [user]";
SqlDataAdapter dp = new SqlDataAdapter(sql, con);
dp.Fill(ds, "[user]");
onRemove = new CacheItemRemovedCallback(this.RemovedCallback);
if (Cache["Key1"] == null)
Cache.Add("Key1", ds, dep, DateTime.Now.AddSeconds(60), TimeSpan.Zero, CacheItemPriority.High, onRemove);
}
public void bind()
{
if (Cache["Key1"] != null)
{
Response.Write("dwad");
GridView1.DataSource = Cache["Key1"] as DataSet;
GridView1.DataBind();
}
else
{
Response.Write("111");
AddItemToCache();
}
}
以上方法你可以详细的看到这个方法很好用。具体我就不多说了。
上述的文件依赖虽然说是与数据库具有一定的依赖关系,可是从本质上说明了文件依赖的使用方法。
二;sql依赖说明:
这里要说明的是,笔者的sql依赖说明是基于程序的。
首先您需要将aspsql的数据库的更改通知起用。
SqlCacheDependencyAdmin.EnableNotifications(
ConfigurationManager.AppSettings["myconnection"].ToString());
然后将起用更改通知的数据库表名,声明出来。
string[] tables = tableName.Text.Split(new Char[] { ';' });
for (int i = 0; i < tables.Length; i++)
tables[i] = tables[i].Trim();
SqlCacheDependencyAdmin.EnableTableForNotifications(
ConfigurationManager.AppSettings["myconnection"].ToString(),tables);
这样如果您申明的表发生了更新,插入,或者是删除操作的话,sql数据变化发出通知给相应的代码来处理。
然后您需要将您使用的页面的顶部加入缓存。
<%@ OutputCache Duration="3600" SqlDependency="数据库名称:表名" VaryByParam="none" %>