Wcf服务中的SqlDependency缓存没有驱逐

时间:2014-04-08 14:35:59

标签: c# wcf caching sqldependency

我有一个wcf服务,我做了一些数据库查询。为了不锤击数据库,我想缓存一些查询。我搜索并发现SqlDependency类和System.Runtime.Caching可用于此目的。然后我发现了这些文章link1link2。我认为第二篇文章提前一步并更新了缓存。但无论我做什么,我都无法让它发挥作用。下面是我的服务代码。

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的默认服务行为。它会影响这种依赖性概念吗?或者我是否应该更改实例上下文模式?

如果需要,我可以提供更多细节。

1 个答案:

答案 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