1. <dd id="erndk"></dd>
                1. .Net cache與cache更新

                  FlyLolo 2019/9/4 11:31:35

                  主要用到 System.Runtime.Caching 框架自動給了一個默認值 MemoryCache.Default; 查看微軟關于MemoryCache的介紹,可以看到它有Add、Get、Set 、 Contains 、Remove等幾個方法, 也就是我們常用的了,比較簡單 網上找了一段對這個封

                  主要用到 System.Runtime.Caching

                  框架自動給了一個默認值 MemoryCache.Default;

                  查看微軟關于MemoryCache的介紹,可以看到它有Add、Get、Set 、 Contains 、Remove等幾個方法, 也就是我們常用的了,比較簡單

                  網上找了一段對這個封裝的代碼:

                  /// <summary>
                      /// Represents a MemoryCacheCache
                      /// </summary>
                      public static class CacheManager
                      {
                          public static ObjectCache Cache
                          {
                              get
                              {
                                  return MemoryCache.Default;
                              }
                          }
                  
                          public static bool Contains(string key)
                          {
                              return Cache.Contains(key);
                          }
                  
                          /// <summary>
                          /// Gets or sets the value associated with the specified key.
                          /// </summary>
                          /// <typeparam name="T">Type</typeparam>
                          /// <param name="key">The key of the value to get.</param>
                          /// <returns>The value associated with the specified key.</returns>
                          public static T Get<T>(string key)
                          {
                              return (T)Cache[key];
                          }
                  
                          /// <summary>
                          /// Adds the specified key and object to the cache.
                          /// </summary>
                          /// <param name="key">key</param>
                          /// <param name="data">Data</param>
                          /// <param name="cacheTime">Cache time</param>
                          public static void Set(string key, object data, int cacheTime)
                          {
                              if (data == null)
                                  return;
                  
                              var policy = new CacheItemPolicy();
                              policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
                              Cache.Set(new CacheItem(key, data), policy);
                          }/// <summary>
                          /// Gets a value indicating whether the value associated with the specified key is cached
                          /// </summary>
                          /// <param name="key">key</param>
                          /// <returns>Result</returns>
                          public static bool IsSet(string key)
                          {
                              return (Cache.Contains(key));
                          }
                  
                          /// <summary>
                          /// Removes the value with the specified key from the cache
                          /// </summary>
                          /// <param name="key">/key</param>
                          public static void Remove(string key)
                          {
                              Cache.Remove(key);
                          }
                  
                          /// <summary>
                          /// Removes items by pattern
                          /// </summary>
                          /// <param name="pattern">pattern</param>
                          public static void RemoveByPattern(string pattern)
                          {
                              var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
                              var keysToRemove = new List<String>();
                  
                              foreach (var item in Cache)
                                  if (regex.IsMatch(item.Key))
                                      keysToRemove.Add(item.Key);
                  
                              foreach (string key in keysToRemove)
                              {
                                  Remove(key);
                              }
                          }
                  
                          /// <summary>
                          /// Clear all cache data
                          /// </summary>
                          public static void Clear()
                          {
                              foreach (var item in Cache)
                                  Remove(item.Key);
                          }

                  框架提供了緩存的更新機制

                  查看MemoryCache的Add方法:Add(CacheItem,?CacheItemPolicy)

                  其中的參數CacheItemPolicy有一個ChangeMonitors屬性, 該屬性可選項為

                  System.Runtime.Caching.CacheEntryChangeMonitor
                  System.Runtime.Caching.FileChangeMonitor
                  System.Runtime.Caching.SqlChangeMonitor

                  可以看出添加cache的時候可以設置此cache的幾種類型的依賴

                  網上看到有FileChangeMonitor的例子, 現在小羅遇到的需求是需要根據系統表來更新緩存,

                  即數據庫中的數據發生了改變, 此時更新本次添加的緩存

                  對上面的代碼添加方法

                          public static void SetWithSql(string key, object data, string connStr, string sql, CacheEntryRemovedCallback callback)
                          {
                              if (data == null)
                                  return;
                  
                              Cache.Add(new CacheItem(key, data), SqlChangePolicy(connStr, sql, callback));
                          }
                  
                   private static CacheItemPolicy SqlChangePolicy(string connStr,string sql, CacheEntryRemovedCallback callback)
                          {
                              SqlDependency.Start(connStr);
                              using (SqlConnection conn = new SqlConnection(connStr))
                              {
                                  using (SqlCommand command = new SqlCommand(sql, conn))
                                  {
                                      command.Notification = null;
                                      conn.Open();
                  
                                      SqlDependency dependency = new SqlDependency(command);
                                      dependency.AddCommandDependency(command);
                  
                                      SqlChangeMonitor monitor = new SqlChangeMonitor(dependency);
                  
                                      CacheItemPolicy policy = new CacheItemPolicy();
                                      policy.ChangeMonitors.Add(monitor);
                  
                                      command.ExecuteScalar();
                                      policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(60*24);
                                      policy.RemovedCallback = callback;
                                      return policy;
                                  }
                              }
                          }

                  添加cache項的時候, 傳入SqlConnection和相應的sql, 目的是當sql對應的查詢結果發生變化的時候, 清除此項緩存

                  注意是清除, 可以看到改方法有一個CacheEntryRemovedCallback參數,當此項被清除后會調用該callback方法

                  如果想"更新", 現在看到這個callback方法應該知道怎么做了

                   

                  看著微軟的幫助一步一步做下來簡單, 但出了一個問題,就是剛Add進去, 馬上CacheEntryRemovedCallback方法就被調用了, 數據改變了? 確認一下沒有,

                  繼續研究幫助,

                  看一下SqlChangeMonitor的構造函數, 參數是SqlDependency

                  SqlDependency是System.Data.SqlClient 命名空間中的,

                  微軟這樣說:SqlDependency 對象都表示應用程序和 SQL Server 實例之間的查詢通知依賴項。 應用程序可以創建 SqlDependency 對象并進行注冊以接收通知通過 OnChangeEventHandler 事件處理程序。

                  原來此對象是數據庫中做監視和通知用的, 被"征用"過來的.

                   

                  這就好辦了, 根據幫助文檔, 發現這個sql的要求真不是一般的嚴格

                  現在說一下這個"sql", 這個sql首先要求是一個select語句,然后:

                  • 必須顯式說明 SELECT 語句中提取的列,并且表名必須限定為兩部分組成的名稱。注意,這意味著語句中引用的所有表都必須處于同一數據庫中。

                  • 語句不能使用星號 (*) 或 table_name.* 語法指定列。

                  • 語句不能使用未命名列或重復的列名。

                  • 語句必須引用基表。

                  • 語句不能引用具有計算列的表。

                  • 在 SELECT 語句中提取的列不能包含聚合表達式,除非語句使用 GROUP BY 表達式。提供 GROUP BY 表達式時,選擇列表便可以包含聚合函數 COUNT_BIG() 或 SUM()。但是,不能為可為空的列指定 SUM()。語句不能指定 HAVING、CUBE 或 ROLLUP。

                  • 在用作簡單表達式的 SELECT 語句中提取的列不能多次顯示。

                  • 語句不能包含 PIVOT 或 UNPIVOT 運算符。

                  • 語句不能包含 UNION、INTERSECT 或 EXCEPT 運算符。

                  • 語句不能引用視圖。

                  • 語句不能包含下列任意一個:DISTINCT、COMPUTE、COMPUTE BY 或 INTO。

                  • 語句不能引用服務器全局變量 (@@variable_name)。

                  • 語句不能引用派生表、臨時表或表變量。

                  • 語句不能從其他數據庫或服務器中引用表或視圖。

                  • 語句不能包含子查詢、外部聯接或自聯接。

                  • 語句不能引用下列大型對象類型:text、ntext 和 image。

                  • 語句不能使用 CONTAINS 或 FREETEXT 全文謂詞。

                  • 語句不能使用行集函數,包括 OPENROWSET 和 OPENQUERY。

                  • 語句不能使用下列任何一個聚合函數:AVG、COUNT(*)、MAX、MIN、STDEV、STDEVP、VAR 或 VARP。

                  • 語句不能使用任何具有不確定性的函數,包括排名函數和開窗函數。

                  • 語句不能包含用戶定義聚合。

                  • 語句不能引用系統表或視圖,包括目錄視圖和動態管理視圖。

                  • 語句不能包含 FOR BROWSE 信息。

                  • 語句不能引用隊列。

                  • 語句不能包含無法更改和無法返回結果的條件語句(如 WHERE 1=0)。

                  • 語句不能指定 READPAST 鎖提示。

                  • 語句不能引用任何 Service Broker QUEUE。

                  • 語句不能引用同義詞。

                  • 語句不能具有基于 double/real 數據類型的比較或表達式。

                  • 語句不得使用 TOP 表達式。

                   

                  多吧, 還有個問題,就是要啟用數據庫的BROKER 

                  ALTER DATABASE database_name SET TRUSTWORTHY ON WITH ROLLBACK IMMEDIATE
                  ALTER DATABASE database_name SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
                  ALTER AUTHORIZATION ON DATABASE::database_name TO sa

                  隨時隨地學軟件編程-關注百度小程序和微信小程序
                  關于找一找教程網

                  本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
                  本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
                  [.Net cache與cache更新]http://www.yachtsalesaustralia.com/tech/detail-90239.html

                  贊(0)
                  關注微信小程序
                  程序員編程王-隨時隨地學編程

                  掃描二維碼或查找【程序員編程王】

                  可以隨時隨地學編程啦!

                  技術文章導航 更多>
                  掃一掃關注最新編程教程
                  国产在线拍揄自揄视频菠萝

                        1. <dd id="erndk"></dd>