문제

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 쿼리의 경우.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top