2012-10-03 31 views
4

我正在使用下面的代碼來緩存「People」表的「Name」列的變化依賴性。但是,如果其他列(如「地址」列)發生更改,則連續觸發並清除緩存。 (ASP.NET 4.0和SQL Server 2008中)SqlCacheDependency/SqlDependency和列

public string GetTheVals() 
{ 
    string vals = HttpContext.Current.Cache["TheCacheKey__X"] as string; 
    if (vals == null) 
    { 
     con = GetConnection(); 
     SqlCommand cmd = new SqlCommand(@" 
SELECT Name 
FROM dbo.People 
", con);    
     con.Open(); 
     SqlCacheDependency sqlDependency = new SqlCacheDependency(cmd); 
     SqlDataReader rdr = null; 

     StringBuilder builder = new StringBuilder(""); 
     rdr = cmd.ExecuteReader(); 
     while (rdr.Read()) 
     { 
      builder.Append(rdr[0].ToString()); 
     } 
     vals = builder.ToString(); 

     HttpContext.Current.Cache.Insert("TheCacheKey__X", vals, sqlDependency, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20)); 
     CloseConnection(con); 
    } 
    return vals; 
} 

它爲什麼會火的時候,改雖說列的值,它是不是在命令的查詢時,結果改變了被解僱?

您也可以爲OnChange事件分配一個委託,當相關命令的結果發生變化時將會觸發 。

http://msdn.microsoft.com/en-us/library/62xk7953.aspx

這也需要國家明確列,所以我們明白,它會過濾掉表的其他列,也不會觸發。

  • 那麼,爲什麼它需要明確指定列名?
  • 它只是爲了讓開發人員意識到他們在做什麼(例如在使用內部連接時)並避免創建會導致最差性能的依賴關係?

在SELECT語句中的預計列必須明確 陳述,和表的名稱前面必須有兩個部分組成的名稱加以限定。注意 這意味着聲明中引用的所有表必須位於 相同的數據庫中。

該聲明可能不會使用星號(*)或table_name。*語法指定 列。

該語句不得包含子查詢,外連接或自連接。

http://msdn.microsoft.com/en-us/library/ms181122(v=sql.105).aspx

回答

3

MS help,但是:

SQL Server發送的訂閱查詢通知時的 一個下列事件發生:包含

  • 行在查詢結果可能已經改變。

  • 訂閱到期。

  • 服務器重新啓動。

  • 查詢通知訂閱無法創建(例如, SELECT語句不符合創建查詢的通知中 規定的要求。

  • 服務器負載過重。

  • 訂閱所依賴的對象被刪除或修改。

注意SQL服務器可以響應生成查詢通知沒有數據,或響應變更爲這一變化 實際上並不影響查詢的結果 事件。例如,當 UPDATE語句更改查詢返回的行之一時,即使對該行的更新沒有更改查詢結果中的 列,也可能觸發 通知。

1

由於我使用SQL緩存依賴項,我注意到你應該考慮很多問題。

其中一個你不能根據列名緩存一個表,如果你想看你的緩存表打開AspNet_SqlCacheTablesForChangeNotification在你的數據庫中。

SELECT TOP 1000 [表名] ,[notificationCreated] ,[changeId] FROM [DBO]。[AspNet_SqlCacheTablesForChangeNotification]

當changeId將被解僱,在更新你會發現,插入或刪除,這將觸發緩存刷新。

對於在命令提示中始終檢查查詢非常重要,如上所述,許多查詢都不受支持。

關心並希望它有幫助。