【问题标题】:How to use SqlCacheDependency?如何使用 SqlCacheDependency?
【发布时间】:2013-04-29 07:25:24
【问题描述】:

我需要为一个依赖于这个查询的表实现 SqlCacheDependency: SELECT Nickname FROM dbo.[User].

我为此创建了一个方法:

private IEnumerable<string> GetNicknamesFromCache()
    {
        const String cacheValueName = "Nicknames";

        var result = HttpRuntime.Cache.Get(cacheValueName) as List<String>;
        if (result == null)
        {
            result = _repository.GetAllNicknames();

            var connectionString = ConfigurationManager.ConnectionStrings["RepositoryContext"].ConnectionString;
            var sqlConnection = new SqlConnection(connectionString);
            var sqlCommand = new SqlCommand("SELECT Nickname FROM dbo.[User]", sqlConnection);
            var sqlDependency = new SqlCacheDependency(sqlCommand);

            HttpRuntime.Cache.Insert(cacheValueName, result, sqlDependency);
        }

        return result;
    }

但是当我运行我的应用程序时它不起作用。 我查看了订阅者列表(sys.dm_qn_subscriptions 表),没有任何记录。

我调查了很多时间,并且已经尝试了各种解决方案,但它们对我不起作用:

  • 使用可信连接并为公共角色设置一些权限:

    GRANT CREATE PROCEDURE TO public
    GRANT CREATE QUEUE TO public
    GRANT CREATE SERVICE TO public
    GRANT SUBSCRIBE QUERY NOTIFICATIONS TO public
    GRANT SELECT ON OBJECT::dbo.[User] TO public
    GRANT RECEIVE ON QueryNotificationErrorsQueue TO public

  • 使用“sa”登录进行连接

  • 使用 aspnet_regsql.exe (aspnet_regsql.exe -S localhost -E -ed -d TestTable -et -t User)
  • 在 web.config 中向 system.webServer 添加配置:

    &lt;caching&gt;
    &lt;sqlCacheDependency enabled="true"&gt;
    &lt;databases&gt;
    &lt;add name="Tmpl" pollTime="5000" connectionStringName="RepositoryContext"/&gt;
    &lt;/databases&gt;
    &lt;/sqlCacheDependency&gt;
    &lt;/caching&gt;

  • 将 SqlDependency.Start() 放入 Global.asax Application_Start 事件中

  • 在不同的 sql server 实例上运行(SQL Server 2008 Express、SQL Server 2008)

但这没有帮助。还是不行。

如何让它发挥作用?

【问题讨论】:

    标签: c# .net sql-server caching service-broker


    【解决方案1】:

    我已经找到解决办法了。

    首先检查是否为您的表启用了Service Broker,并在需要时启用它:

    SELECT name, is_broker_enabled FROM sys.databases WHERE name = '<databaseName>'
    
    ALTER DATABASE <databaseName> SET enable_broker WITH ROLLBACK IMMEDIATE
    

    接下来在 SQL Server 中创建新角色sql_dependency_role,为其授予权限并将角色授予用户:

    EXEC sp_addrole 'sql_dependency_role'
    
    GRANT CREATE PROCEDURE to sql_dependency_role
    GRANT CREATE QUEUE to sql_dependency_role
    GRANT CREATE SERVICE to sql_dependency_role
    GRANT REFERENCES on CONTRACT::[http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification] to sql_dependency_role
    GRANT VIEW DEFINITION TO sql_dependency_role
    GRANT SELECT to sql_dependency_role
    GRANT SUBSCRIBE QUERY NOTIFICATIONS TO sql_dependency_role
    GRANT RECEIVE ON QueryNotificationErrorsQueue TO sql_dependency_role
    
    EXEC sp_addrolemember 'sql_dependency_role', '<userName>'
    

    然后添加 C# 代码以使用 SqlCacheDependencySqlDependency(大部分方式相同)。

    我改变了我的方法,现在看起来像这样:

    private IEnumerable<string> GetNicknamesFromCache()
        {
            const String cacheValueName = "Nicknames";
    
            var result = HttpRuntime.Cache.Get(cacheValueName) as List<String>;
            if (result == null)
            {
                result = _repository.GetAllNicknames();
    
                using (var connection = new SqlConnection(_config.ConnectionString))
                {
                    connection.Open();
    
                    SqlDependency.Start(_config.ConnectionString);
                    var command = new SqlCommand("SELECT Nickname FROM dbo.[User]", connection);
                    var dependency = new SqlCacheDependency(command);
                    HttpRuntime.Cache.Insert(cacheValueName, result, dependency);
    
                    command.ExecuteNonQuery();
                }
            }
    
            return result;
        }
    

    现在可以正常使用了。

    不要忘记在创建SqlCacheDependencySqlDependency 之前调用SqlDependency.Start 方法并在最后执行您的命令。

    【讨论】:

    • 是否有必要像您在这里所做的那样保持连接打开,或者您可以关闭/处理它吗?
    • 在上面回答我自己的问题 - 有必要保持此连接打开,以便服务代理可以发送这些通知。如果您有许多需要刷新的缓存条目,这会使设计变得有点困难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    相关资源
    最近更新 更多