SQLDependency
クラスでクエリ通知を調べています。簡単な実例を作成するのは簡単ですが、何かが足りないように感じます。テーブルが 1 つ、依存関係が 1 つの単純な例を過ぎて から、どの依存関係がコールバックをトリガーしたかをどのように特定できるのか疑問に思います。
ちょっと説明が難しいので、簡単な例を以下に示します。が呼び出されたときAChange()
に、依存関係内の sql を見ることができず、関連するキャッシュ オブジェクトへの参照がありません。
それで、男の子は何をするのですか?
- オプション 1 - 追跡したいオブジェクトごとに個別の関数を作成し、コールバックでキャッシュ キー (または関連情報) をハード コードします。これは汚いと感じ、新しいコードを展開せずに新しいキャッシュ項目を追加する可能性を排除します--ewww.
- オプション 2 - Dependency
Id
プロパティと並行追跡構造を使用する
何か足りないだけですか?SQLDependency
これは構造上の欠陥でしょうか?このトピックに関する 20 の異なる記事を見てきましたが、それらのすべてに同じ穴があるようです。提案?
コードサンプル
public class DependencyCache{
public static string cacheName = "Client1";
public static MemoryCache memCache = new MemoryCache(cacheName);
public DependencyCache() {
SqlDependency.Start(connString);
}
private static string GetSQL() {
return "select someString FROM dbo.TestTable";
}
public void DoTest() {
if (memCache["TEST_KEY"] != null ) {
Debug.WriteLine("resources found in cache");
return;
}
Cache_GetData();
}
private void Cache_GetData() {
SqlConnection oConn;
SqlCommand oCmd;
SqlDependency oDep;
SqlDataReader oRS;
List<string> stuff = new List<string>();
CacheItemPolicy policy = new CacheItemPolicy();
SqlDependency.Start(connString);
using (oConn = new SqlConnection(connString) ) {
using (oCmd = new SqlCommand(GetSQL(), oConn) ) {
oDep = new SqlDependency(oCmd);
oConn.Open();
oRS = oCmd.ExecuteReader();
while(oRS.Read() ) {
resources.Add( oRS.GetString(0) );
}
oDep.OnChange += new OnChangeEventHandler (AChange);
}
}
memCache.Set("TEST_KEY", stuff, policy);
}
private void AChange( object sender, SqlNotificationEventArgs e) {
string msg= "Dependency Change \nINFO: {0} : SOURCE {1} :TYPE: {2}";
Debug.WriteLine(String.Format(msg, e.Info, e.Source, e.Type));
// If multiple queries use this as a callback how can i figure
// out WHAT QUERY TRIGGERED the change?
// I can't figure out how to tell multiple dependency objects apart
((SqlDependency)sender).OnChange -= Cache_SqlDependency_OnChange;
Cache_GetData(); //reload data
}
}