キャッシュと SqlCacheDependency (ASP.NET MVC)
-
20-09-2019 - |
質問
レコードのサブセットを返す必要があるため、次のコマンドを使用します。
using (SqlCommand command = new SqlCommand(
"SELECT ID, Name, Flag, IsDefault FROM (SELECT ROW_NUMBER() OVER (ORDER BY @OrderBy DESC) as Row, ID, Name, Flag, IsDefault FROM dbo.Languages) results WHERE Row BETWEEN ((@Page - 1) * @ItemsPerPage + 1) AND (@Page * @ItemsPerPage)",
connection))
次のように宣言された SqlCacheDependency を設定します。
SqlCacheDependency cacheDependency = new SqlCacheDependency(command);
しかし、command.ExecuteReader() 命令を実行した直後、 変更されました クエリの結果をまったく変更していないにもかかわらず、SqlCacheDependency オブジェクトの基本プロパティが true になります。このため、このクエリの結果はキャッシュに保持されません。
HttpRuntime.Cache.Insert( cacheKey, list, cacheDependency, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(AppConfiguration.CacheExpiration.VeryLowActivity));
コマンドにSELECT文が2つあるからでしょうか?ROW_NUMBER()ですか?「はい」の場合、結果をページ分割する他の方法はありますか?
助けてください!何時間も経った後、少しでも感謝されるでしょう。ありがとう
解決
同じ問題に遭遇し、同じ答えをオンラインで見つけることができず、プロファイラーからの XML 無効なサブスクリプション応答を再調査していました。
msdn サポート サイトでコードの順序が少し異なる例を見つけました。試してみたところ、問題に気づきました。コマンド オブジェクトとキャッシュ依存関係オブジェクトを作成するまでは、接続オブジェクトを開かないでください。従わなければならない順序は次のとおりです。そうすればすべてうまくいきます。
- 必ず通知 (SqlCahceDependencyAdmin) を有効にし、最初に SqlDependency.Start を実行してください。
- 接続オブジェクトを作成する
- コマンド オブジェクトを作成し、コマンド テキスト、タイプ、接続オブジェクトを割り当てます (コンストラクターの任意の組み合わせ、プロパティの設定、または CreateCommand の使用)。
- SQLキャッシュ依存関係オブジェクトを作成する
- 接続オブジェクトを開きます
- クエリを実行する
- 依存関係を使用してアイテムをキャッシュに追加します。
この順序に従い、select ステートメントの他のすべての要件に従い、権限の問題がなければ、これは機能します。
この問題は、.NET Framework による接続の管理方法、具体的にはどのような設定が設定されているかに関係していると思います。SQLコマンドのテストでこれをオーバーライドしようとしましたが、うまくいきませんでした。これは単なる推測です。私が知っているのは、順序を変更すると問題がすぐに解決されたということです。
以下のmsdn投稿からそれをつなぎ合わせることができました。
この投稿は、無効なサブスクリプションの最も一般的な原因の 1 つであり、.Net クライアントが通知に必要なプロパティとは対照的にどのようにプロパティを設定するかを示しています。
この投稿は、私と同じように、コードを最も単純な形式に削減したユーザーからのものでした。私の元のコードパターンは彼のものと似ていました。
それから私はこの投稿を見つけました。これも問題を非常に単純に軽減したもので、テーブルに2つの部分からなる名前が必要という単純な問題だけでした。彼の場合は、提案によって問題が解決しました。彼のコードを見た後、主な違いは、コマンド オブジェクトと依存関係オブジェクトが作成されるまで接続オブジェクトを開くのを待機していることに気付きました。私の唯一の仮定は、内部でのことです(まだリフレクターを開始していないため、単なる仮定です)この関連付けにより、Connectionオブジェクトが異なる方法で開かれるか、イベントとコマンドの順序が異なることが発生します。
これが同様の問題を抱えている他の人に役立つことを願っています。
他のヒント
ただの推測が、あなたのSELECT
文がORDER BY
句を持っていないので、それができる?
あなたが明示的に順序を指定しない場合、クエリは任意の順序でそれが実行されるたびに結果を返すようにするために、それが可能です。多分これはSqlCacheDependency
オブジェクトが結果が変更されていると考えるのが原因とされます。
ORDER BY
句を追加してみてください。
SELECT ID, Name, Flag, IsDefault
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY @OrderBy DESC) AS Row,
ID, Name, Flag, IsDefault
FROM dbo.Languages
) AS results
WHERE Row BETWEEN ((@Page - 1) * @ItemsPerPage + 1) AND (@Page * @ItemsPerPage)
ORDER BY Row
私は SqlCacheDependency の専門家ではありません。実際、私自身の問題に対する答えを探していたときにこの質問を見つけました。ただし、SqlCacheDependency が機能しない理由は、SQL にネストされたサブクエリが含まれているためだと思います。
SQL で使用できるものと使用できないものをリストしたドキュメントを参照してください。 通知用のクエリの作成
「....ステートメントにはサブクエリ、外部結合、または自己結合を含めることはできません....」
Redgate の担当者からの貴重なトラブルシューティング情報もここで見つけました。 SQL 2005 クエリ通知の使用と監視 それは私自身の問題を解決するのに役立ちました:SQL プロファイラーを使用して彼が提案した QN イベントを追跡することで、接続が「SET ARITHABORT OFF」オプションを誤って使用しており、通知が失敗する原因となっていることがわかりました。