web-dev-qa-db-ja.com

SqlCacheDependencyの使い方は?

このクエリに依存するテーブルに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 table)そしてレコードはありませんでした。

私は多くの時間を調査し、すでにさまざまな解決策を試しましたが、それらは私にとってはうまくいきません:

  • 信頼できる接続を使用し、パブリックロールにいくつかの権限を設定します。

    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.asaxApplication_Startイベントに配置します

  • sQL Serverのさまざまなインスタンスで実行(SQL Server 2008 Express、SQL Server 2008)

しかし、それは役に立ちませんでした。それでも機能しません。

どうすればそれを機能させることができますか?

14

私はすでに解決策を見つけました。

最初に、テーブルでService Brokerが有効になっているかどうかを確認し、必要に応じて有効にします。

SELECT name, is_broker_enabled FROM sys.databases WHERE name = '<databaseName>'

ALTER DATABASE <databaseName> SET enable_broker WITH ROLLBACK IMMEDIATE

次に、SQLServerで新しいロール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>'

その後、SqlCacheDependencyまたはSqlDependencyを操作するためのC#コードを追加します(ほとんど同じ方法で)。

メソッドを変更しましたが、次のようになります。

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;
    }

今では正常に動作します。

SqlCacheDependencyまたはSqlDependencyを作成する前にSqlDependency.Startメソッドを呼び出し、最後にコマンドを実行することを忘れないでください。

19