我有一个wcf服务,我做了一些数据库查询。为了不锤击数据库,我想缓存一些查询。我搜索并发现SqlDependency
类和System.Runtime.Caching
可用于此目的。然后我发现了这些文章link1,link2。我认为第二篇文章提前一步并更新了缓存。但无论我做什么,我都无法让它发挥作用。下面是我的服务代码。
public class LocalDatabase : ILocalDatabase
{
public LocalDatabase ()
{
SqlDependency.Start(connectionString);
_cache = MemoryCache.Default;
}
public List<string> GetData ( string value )
{
if ( MemoryCache.Default["exceptions"] == null )
{
// Create a policy.
var policy = new CacheItemPolicy();
// Load data into Cache Item.
var exceptions = new List<string>();
using ( var connection = new SqlConnection(ConnectionString) )
using ( var command = new SqlCommand("SELECT [Exception] FROM [myDb].[dbo].[ServiceException]", connection) )
{
var sqlDependency = new SqlDependency();
sqlDependency.AddCommandDependency(command);
connection.Open();
using ( var result = command.ExecuteReader() )
while ( result.Read() )
exceptions.Add(result.GetString(0));
var sqlMonitor = new SqlChangeMonitor(sqlDependency);
policy.ChangeMonitors.Add(sqlMonitor);
/// Events
//sqlDependency.OnChange += sqlDep_OnChange;
//policy.UpdateCallback = Exceptions_CacheUpdateCallback;
}
// Set Cache Item into cache with the policy.
MemoryCache.Default.Add("exceptions", exceptions, policy);
}
return MemoryCache.Default.Get("exceptions") as List<string>;
}
void sqlDep_OnChange ( object sender, SqlNotificationEventArgs e )
{
/// not firing this
}
void Exceptions_CacheUpdateCallback ( CacheEntryUpdateArguments args )
{
/// not firing this either
}
}
在第一篇文章中,它甚至没有绑定事件,但仍然声称它有效,因此我一起删除了事件处理程序,但没有任何变化。问题是在第一次调用服务方法时它从db加载缓存,而下一次调用从缓存中获取它们的响应非常好,但是当db更改发生插入或更新或删除时,它不会逐出缓存,因此它不断给出已弃用的结果。然后我取消了对事件处理程序的注释,这些事件也从未被解雇过。
编辑:顺便说一句,我也在sql server上执行了这两个命令。
ALTER DATABASE database_name SET TRUSTWORTHY ON WITH ROLLBACK IMMEDIATE
ALTER DATABASE database_name SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
我可能会在这里错过什么?
Edit2:据我所知,我的其他问题是InstanceContextMode.PerCall
的默认服务行为。它会影响这种依赖性概念吗?或者我是否应该更改实例上下文模式?
如果需要,我可以提供更多细节。
答案 0 :(得分:0)
原来我已经以错误的格式构造了我的sql查询,这违反了声明为here的规则。下面是我的错误和纠正的样本。
我的错误查询:
SELECT p.Id, d.Id
FROM [MyDb].[dbo].[Personnel] p, [MyDb].[dbo].[Department] d
WHERE p.DepartmentId = d.Id
更正后的版本:
SELECT [dbo].[Personnel].Id, [dbo].[Department].Id
FROM [dbo].[Personnel] INNER JOIN [dbo].[Department]
ON [dbo].[Personnel].DepartmentId = [dbo].[Department].Id