c# - 如何使用SqlCacheDependency?

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

我需要为依赖于此查询的表实现 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 表),没有任何记录。

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

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

    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添加配置:

    <caching>
    <sqlCacheDependency enabled="true">
    <databases>
    <add name="Tmpl" pollTime="5000" connectionStringName="RepositoryContext"/>
    </databases>
    </sqlCacheDependency>
    </caching>

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

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

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

如何让它发挥作用?

最佳答案

我已经找到了解决方案。

首先检查是否为您的表启用了 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 方法并在最后执行您的命令。

关于c# - 如何使用SqlCacheDependency?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16383513/

相关文章:

c# - 如何将多个 Alter 存储过程脚本作为一个脚本运行?

c# - Ninject Singleton 范围内部控制台应用程序

c# - 如何调用顶级构造函数?

c# - 如何在单独的 AppDomain 中运行方法?

c# - Net Core 3.0 中没有 UseDatabaseErrorPage() 扩展方法

c# - 带有 IdentityDbContext 的 EF6 多对多无效列名

sql-server - Microsoft SQL 查询 - 从第二个表中返回最后一条记录

c# - 反序列化 System.Collections.ArrayList 类型的对象 - AppFabric 缓存错误

c# - 安全正确的结构编码

.net - DateTime 的 WebApi 序列化 - 如何反序列化?