sna*_*yko 8 asp.net asp.net-mvc caching sql-server-2005 sql-server-2008
我有个问题.无法找到如何使OutputCache SQLDependency依赖于数据库表中的一行.例如,我有一个带有一个参数的控制器.
ActionResult Index(int? id)
Run Code Online (Sandbox Code Playgroud)
对于具有相同id的每个请求,我需要检查数据库表table1(id int,last_updated datetime).如果id = id和last_updated的行未更改.
我使用sql server 2005或更高版本.
我应该使用哪种策略?
我试着用:
[OutputCache(Duration = int.MaxValue, VaryByParam = "id",
SqlDependency = "DatabaseName:table1")]
Run Code Online (Sandbox Code Playgroud)
但它适用于整个表格的更改.
为避免针对每个网页请求(通常是昂贵的操作)访问数据库,可以使用对象缓存(在.NET 4.0中引入).这将导致快速提供网页,因为所有内容都将直接从内存中处理.仅当数据实际更改时,或者由于资源限制或CacheItemPolicy设置而导致缓存从内存中逐出时,才会发生数据库操作.
在这种情况下使用的实用策略如下.
步骤1.在您的Model方法中,正在修改/添加/删除"id"行的数据,完成该数据库操作,然后:
第2步.尽可能从缓存中检索对象,仅在必要时从db刷新:
(MemoryCache类是ObjectCache类的具体实现).
使用这种方法,根本不需要使用Controller方法上的OutputCache,并且数据缓存决策都将完全封装在Model中.我们会更清楚地分离关注点; 更高的效率,更好的响应时间和更高的可扩展性; 并减少对昂贵的数据库操作的依赖.
[OutputCache (Duration=int.MaxValue VaryByParam="None" VaryByCustom="SqlRow")]
Run Code Online (Sandbox Code Playgroud)
在您的 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);
}
Run Code Online (Sandbox Code Playgroud)