如何使用SqlDependency的OutputCache依赖于每个请求的数据库中的行?

时间:2012-03-06 16:25:57

标签: asp.net asp.net-mvc sql-server-2008 sql-server-2005 caching

我有问题。无法找到如何使OutputCache SQLDependency依赖于数据库表中的一行。 例如。 我有一个带有一个参数的控制器。

ActionResult Index(int? id)

对于每个具有相同id的请求,我需要检查数据库表table1(id int,last_updated datetime)。如果id = id和last_updated的行没有改变。

我使用sql server 2005或更高版本。

我应该使用哪种策略?

我试图使用:

[OutputCache(Duration = int.MaxValue, VaryByParam = "id", 
    SqlDependency = "DatabaseName:table1")]

但它适用于整个表的更改。

2 个答案:

答案 0 :(得分:7)

为避免针对每个网页请求(通常是昂贵的操作)访问数据库,可以使用对象缓存(在.NET 4.0中引入)。这将导致快速提供网页,因为所有内容都将直接从内存中处理。仅当数据实际更改时,或者由于资源限制或CacheItemPolicy设置而导致缓存从内存中逐出时,才会发生数据库操作。

本案例中使用的实用策略如下:

步骤-1。在您的Model方法中,正在修改/添加/删除“id”行的数据,完成该数据库操作,然后:

步骤-2。尽可能从缓存中检索对象,仅在必要时从数据库刷新:

  • 从Controller操作方法中,调用Model方法,该方法返回由“id”参数标识的对象;
  • 在您的Model方法中,检查此ID的缓存。如果为null,则从数据库中检索数据并像通常那样构建对象,然后将完整对象存储在缓存中;
  • 从Model方法中,将缓存的内容(即此id的特定对象)返回给调用Controller操作方法,然后让action方法像往常一样填充并提供View。

MemoryCache类是ObjectCache类的具体实现。)

使用这种方法,根本不需要使用Controller方法上的OutputCache,并且数据缓存决策都将完全封装在Model中。我们会更清楚地分离关注点;更高的效率,更好的响应时间和更高的可扩展性;并且减少了对昂贵的数据库操作的依赖。

答案 1 :(得分:3)

[OutputCache (Duration=int.MaxValue VaryByParam="None" VaryByCustom="SqlRow")]

在你的global.asax中你必须遵循。

Public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
  if(arg.ToLower() == "sqlrow") 
  { 
     using(SqlConnection conn = new SqlConnection(... ) )
     {
         conn.Open();
         var cmd = conn.CreateCommand();
         var id = context.QueryString["id"];
         cmd.CommandText = "SELECT LastModifiedTime FROM Table WHERE ID = @id";
         cmd.Parameters.Add( "id", id );
         return cmd.ExecuteScalar();
     }
  } 
  return base.GetVaryByCustomString(context, arg); 
}