.NET 4.0 使用 SqlChangeMonitor 的 MemoryCache






4.65/5 (14投票s)
如何在 .NET 4.0 中将 SqlChangeMonitor 与新的 MemoryCache 类一起使用。
摘要
互联网上关于如何在 .NET 4.0 中将 SqlChangeMonitor
与新的 MemoryCache
类一起使用的文档不多,所以我认为我应该添加我的示例。
数据库准备
第一步是为 SqlChangeMonitor
准备您的数据库。 此功能使用 SQL Server Service Broker 来设置一个通知事件,该事件会在数据发生更改时触发以通知,数据更改会更改查询的返回记录集,因此我们必须在数据库上启用 Service Broker。
ALTER DATABASE database_name SET TRUSTWORTHY ON WITH ROLLBACK IMMEDIATE
ALTER DATABASE database_name SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
ALTER AUTHORIZATION ON DATABASE::database_name TO sa
有了这个,我们就可以继续在代码中设置缓存了……
代码
public bool IsInMaintenanceMode()
{
bool inMaintenanceMode;
if (MemoryCache.Default["MaintenanceMode"] == null)
{
CacheItemPolicy policy = new CacheItemPolicy();
string connStr = "MY CONNECTION STRING";
SqlDependency.Start(connStr);
using (SqlConnection conn = new SqlConnection(connStr))
{
using (SqlCommand command = new SqlCommand(
"Select MaintenanceMode From dbo.MaintenanceMode", conn))
{
command.Notification = null;
SqlDependency dep = new SqlDependency();
dep.AddCommandDependency(command);
conn.Open();
inMaintenanceMode = (bool)command.ExecuteScalar();
SqlChangeMonitor monitor = new SqlChangeMonitor(dep);
policy.ChangeMonitors.Add(monitor);
}
}
MemoryCache.Default.Add("MaintenanceMode", inMaintenanceMode, policy);
}
else
{
inMaintenanceMode = (bool)MemoryCache.Default.Get("MaintenanceMode");
}
return inMaintenanceMode;
}
此代码是一种简单的缓存值的方法,该值指定应用程序当前是否处于维护模式。 dbo.Maintenance
表包含一个单行,其中包含一个单比特列。 此代码将允许您的应用程序持续检查是否应该进入维护模式,而不会过度访问您的数据库。
当数据库中的值发生更改时,应用程序会收到通知,提示它应使缓存失效。 然后,在下次调用 IsInMaintenanceMode
时,MemoryCache.Default["MaintenanceMode"]
返回 null
,导致它重新注册通知。 这正是我们想要的。
注释
- 您**必须**首先调用
SqlDependency.Start
,否则它将无法工作。 - 您的 SQL 命令**必须**遵循此处的准则。 关于如何构建查询,有很多需要考虑的事情,因此请密切注意此文档。
- 将命令对象添加到
SqlDependency
对象后,您**必须**至少执行一次命令,否则它将不会注册通知。 - 执行一次命令后,您可以释放您的连接。 在后台,.NET 将保持与 SQL Server 的连接打开,以侦听通知。
我希望这对某些人有所帮助。 我知道我花了**太多**时间寻找根本不存在的文档。
编辑
- 我已经附加了一个示例项目,说明了上面代码的使用。 这是一个简单的控制台应用程序,它只是展示了您如何使用它。 运行附加代码中的 SQL 脚本以创建一个数据库,然后运行该应用程序。 运行后,更改表中“
MaintenanceMode
”的值。 您将看到它何时访问数据库,以及何时使用缓存。 我希望这能提供一个更好的用法示例。