어떤 sqldependency가 트리거 된 변화 기능을 파악하는 방법은 무엇입니까?
-
11-12-2019 - |
문제
SQLDependency
클래스에서 쿼리 알림을 탐색하고 있습니다. 간단한 작업 예제를 구축하는 것은 쉽지만, 내가 뭔가를 놓치는 것처럼 느껴집니다. 간단한 한 테이블 / 일체형 예제를 지나가면 이 콜백을 트리거 한 종속성을 어떻게 알 수 있습니까?
나는 약간의 어려움을 겪고 있으므로 아래의 간단한 예를 포함했습니다. AChange()
가 호출되면 종속성 내부의 SQL을 볼 수 없으며 연관된 캐시 객체에 대한 참조가 없습니다.
그래서 소년이 뭐니?
- 옵션 1 - CACHE-KEY (또는 관련 정보)를 콜백에서 추적하고 하드 코딩하려는 각 개체에 대해 별개의 함수를 만듭니다. 이것은 더러운 느낌을줌으로써 새로운 코드를 배치하지 않고 새로운 캐시 항목을 추가 할 수있는 긍정적 인 것을 제거합니다.
- 옵션 2 - 종속성
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 } }
해결책
first 및 foremost : 핸들러가 이전에 을 설정해야합니다.
.
oDep = new SqlDependency(oCmd);
oConn.Open();
oDep.OnChange += new OnChangeEventHandler (AChange);
oRS = oCmd.ExecuteReader();
while(oRS.Read() ) {
resources.Add( oRS.GetString(0) );
}
알림이 손실 될 수 있고 콜백이 호출되지 않을 때 창이 있습니다.
이제 질문에 대해서 : 각 쿼리에 대해 별도의 콜백을 사용해야합니다. 이것은 성가신 것처럼 보일 수 있지만 실제로는 람다를 사용하여 사소합니다. 다음과 같은 것 :
.
oDep = new SqlDependency(oCmd);
oConn.Open();
oDep.OnChange += (sender, e) =>
{
string msg = "Dependency Change \nINFO: {0} : SOURCE {1} :TYPE: {2}";
Debug.WriteLine(String.Format(msg, e.Info, e.Source, e.Type));
// The command that trigger the notification is captured in the context:
// is oCmd
//
// You can now call a handler passing in the relevant info:
//
Reload_Data(oCmd, ...);
};
oRS = oCmd.ExecuteReader();
...
항상 알림 원본, 정보 및 유형을 항상 확인하십시오 항상 을 기억하십시오. 그렇지 않으면 잘못된 쿼리와 같이 데이터 변경보다 기타 의 이유로 알림을받을 때 광고 없음을 회전 할 위험이 있습니다. 사이드 코멘트로서 좋은 캐시 디자인이 무효화 된 캐시를 새로 고치지 않고 캐시 된 항목을 무효화하지 않으며 다음 요청 이 실제로 새 항목을 가져올 수 있습니다. '능동적 인'접근 방식으로 필요하지 않은 경우에도 캐시 된 항목을 새로 고치고 있습니다. 오류 처리 및 적절한 스레드 동기화 (둘 다 필요한)에서 나오기 전에 여러 번 새로 고침하십시오.
마지막으로 "nofollow"> LinqTocache 를 봅니다. 하지만 Linq 쿼리의 경우.