1. 程式人生 > WINDOWS開發 >C#-Redis幫助類(.Net Framework)

C#-Redis幫助類(.Net Framework)

  1. Redis簡要介紹

  引用百度百科的話,就是:Redis(Remote Dictionary Server ),即遠端字典服務,是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value NoSQL資料庫,並提供多種語言的API。

  Redis的主要使用場景:快取、訊息佇列、頻繁讀寫等,還有很多等等,這個可以隨處搜到;Redis的優勢就是讀寫資料效能高,支援資料型別豐富,所有操作都是原子性,成功或者不成功,現在還支援釋出訂閱等特性。

  2. .Net Framework操作Redis

  建立新專案等等其他的我就不截圖了,我使用的是VS2019專業版,.Net Framework 4.7.2,都行,這個都支援,無非可能是類庫更新導致有些最新功能你不能用。

  技術分享圖片

  看下專案的一個結構,當前選中的為啟動專案,控制檯應用程式,另外兩個是用到的自定義類庫,RedisHelp為自定義的Redis幫助類庫,用到的Nuget包為StackExchange.Redis2.1.30,LogManager是一個寫日誌的幫助類;

  技術分享圖片

  ①配置檔案配置,RedisTest專案展開,開啟App.config,新增Redis服務的IP和埠,<add name="RedisExchangeHosts" connectionString="127.0.0.1:6379,allowadmin=true" />

  技術分享圖片

  ②ConnectionMultiplexer封裝

  ConnectionMultiplexer物件是StackExchange.Redis最中樞的物件。這個類的例項需要被整個應用程式域共享和重用的,所以不需要在每個操作中不停的建立該物件的例項,一般都是使用單例來建立和存放這個物件,提高程式執行的效率,這個在官網上也有說明的。

技術分享圖片
  1     /// <summary>
  2     /// ConnectionMultiplexer物件管理幫助類
  3     /// </summary>
  4     public static class RedisConnectionHelp
  5     {
  6         #region
屬性 7 8 /// <summary> 9 /// 系統自定義Key字首 10 /// </summary> 11 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? ""; 12 13 /// <summary> 14 /// Redis連結字串 15 /// </summary> 16 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 17 18 /// <summary> 19 /// 連結快取池 20 /// </summary> 21 private static readonly ConcurrentDictionary<string,ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string,ConnectionMultiplexer>(); 22 23 #endregion 24 25 #region 單例和構造 26 27 /// <summary> 28 /// 29 /// </summary> 30 private static readonly object Locker = new object(); 31 32 /// <summary> 33 /// 單例 34 /// </summary> 35 private static ConnectionMultiplexer _instance; 36 37 38 /// <summary> 39 /// 單例獲取 40 /// </summary> 41 public static ConnectionMultiplexer Instance 42 { 43 get 44 { 45 if (_instance == null) 46 { 47 lock (Locker) 48 { 49 if (_instance == null || !_instance.IsConnected) 50 { 51 _instance = GetManager(); 52 } 53 } 54 } 55 return _instance; 56 } 57 } 58 59 /// <summary> 60 /// 快取獲取 61 /// </summary> 62 /// <param name="connectionString"></param> 63 /// <returns></returns> 64 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString) 65 { 66 if (!ConnectionCache.ContainsKey(connectionString)) 67 { 68 ConnectionCache[connectionString] = GetManager(connectionString); 69 } 70 return ConnectionCache[connectionString]; 71 } 72 73 /// <summary> 74 /// 獲取連結 75 /// </summary> 76 /// <param name="connectionString"></param> 77 /// <returns></returns> 78 private static ConnectionMultiplexer GetManager(string connectionString = null) 79 { 80 connectionString = connectionString ?? RedisConnectionString; 81 var connect = ConnectionMultiplexer.Connect(connectionString); 82 83 //註冊如下事件 84 connect.ConnectionFailed += MuxerConnectionFailed; 85 connect.ConnectionRestored += MuxerConnectionRestored; 86 connect.ErrorMessage += MuxerErrorMessage; 87 connect.ConfigurationChanged += MuxerConfigurationChanged; 88 connect.HashSlotMoved += MuxerHashSlotMoved; 89 connect.InternalError += MuxerInternalError; 90 91 return connect; 92 } 93 94 #endregion 95 96 #region 事件 97 98 /// <summary> 99 /// 配置更改時 100 /// </summary> 101 /// <param name="sender"></param> 102 /// <param name="e"></param> 103 private static void MuxerConfigurationChanged(object sender,EndPointEventArgs e) 104 { 105 Console.WriteLine("Configuration changed: " + e.EndPoint); 106 } 107 108 /// <summary> 109 /// 發生錯誤時 110 /// </summary> 111 /// <param name="sender"></param> 112 /// <param name="e"></param> 113 private static void MuxerErrorMessage(object sender,RedisErrorEventArgs e) 114 { 115 Console.WriteLine("ErrorMessage: " + e.Message); 116 } 117 118 /// <summary> 119 /// 重新建立連線之前的錯誤 120 /// </summary> 121 /// <param name="sender"></param> 122 /// <param name="e"></param> 123 private static void MuxerConnectionRestored(object sender,ConnectionFailedEventArgs e) 124 { 125 Console.WriteLine("ConnectionRestored: " + e.EndPoint); 126 } 127 128 /// <summary> 129 /// 連線失敗 , 如果重新連線成功你將不會收到這個通知 130 /// </summary> 131 /// <param name="sender"></param> 132 /// <param name="e"></param> 133 private static void MuxerConnectionFailed(object sender,ConnectionFailedEventArgs e) 134 { 135 Console.WriteLine("重新連線:Endpoint failed: " + e.EndPoint + "," + e.FailureType + (e.Exception == null ? "" : ("," + e.Exception.Message))); 136 } 137 138 /// <summary> 139 /// 更改叢集 140 /// </summary> 141 /// <param name="sender"></param> 142 /// <param name="e"></param> 143 private static void MuxerHashSlotMoved(object sender,HashSlotMovedEventArgs e) 144 { 145 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ",OldEndPoint" + e.OldEndPoint); 146 } 147 148 /// <summary> 149 /// redis類庫錯誤 150 /// </summary> 151 /// <param name="sender"></param> 152 /// <param name="e"></param> 153 private static void MuxerInternalError(object sender,InternalErrorEventArgs e) 154 { 155 Console.WriteLine("InternalError:Message" + e.Exception.Message); 156 } 157 158 #endregion 事件 159 }
View Code

  ③RedisHelper通用操作類封裝

技術分享圖片
   1     /// <summary>
   2     /// Redis操作類
   3     /// </summary>
   4     public class RedisHelper
   5     {
   6         #region 屬性
   7 
   8         /// <summary>
   9         /// DB庫
  10         /// </summary>
  11         private int DbNum { get; }
  12 
  13         /// <summary>
  14         /// Redis連結
  15         /// </summary>
  16         private readonly ConnectionMultiplexer _conn;
  17 
  18         /// <summary>
  19         /// 字首
  20         /// </summary>
  21         public string CustomKey;
  22 
  23         #endregion
  24 
  25         #region 建構函式
  26 
  27         /// <summary>
  28         /// 預設構造
  29         /// </summary>
  30         /// <param name="dbNum">DB索引</param>
  31         public RedisHelper(int dbNum = 0)
  32                 : this(dbNum,null)
  33         {
  34         }
  35 
  36         /// <summary>
  37         /// 構造
  38         /// </summary>
  39         /// <param name="dbNum"></param>
  40         /// <param name="readWriteHosts"></param>
  41         public RedisHelper(int dbNum,string readWriteHosts)
  42         {
  43             DbNum = dbNum;
  44             _conn =
  45                 string.IsNullOrWhiteSpace(readWriteHosts) ?
  46                 RedisConnectionHelp.Instance :
  47                 RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts);
  48         }
  49 
  50         #endregion 建構函式
  51 
  52         #region String
  53 
  54         #region 同步方法
  55 
  56         /// <summary>
  57         /// 儲存單個key value
  58         /// </summary>
  59         /// <param name="key">Redis Key</param>
  60         /// <param name="value">儲存的值</param>
  61         /// <param name="expiry">過期時間</param>
  62         /// <returns></returns>
  63         public bool StringSet(string key,string value,TimeSpan? expiry = default(TimeSpan?))
  64         {
  65             key = AddSysCustomKey(key);
  66             return Do(db => db.StringSet(key,value,expiry));
  67         }
  68 
  69         /// <summary>
  70         /// 儲存多個key value
  71         /// </summary>
  72         /// <param name="keyValues">鍵值對</param>
  73         /// <returns></returns>
  74         public bool StringSet(List<KeyValuePair<RedisKey,RedisValue>> keyValues)
  75         {
  76             List<KeyValuePair<RedisKey,RedisValue>> newkeyValues =
  77                 keyValues.Select(p => new KeyValuePair<RedisKey,RedisValue>(AddSysCustomKey(p.Key),p.Value)).ToList();
  78             return Do(db => db.StringSet(newkeyValues.ToArray()));
  79         }
  80 
  81         /// <summary>
  82         /// 儲存一個物件
  83         /// </summary>
  84         /// <typeparam name="T"></typeparam>
  85         /// <param name="key"></param>
  86         /// <param name="obj"></param>
  87         /// <param name="expiry"></param>
  88         /// <returns></returns>
  89         public bool StringSet<T>(string key,T obj,TimeSpan? expiry = default(TimeSpan?))
  90         {
  91             key = AddSysCustomKey(key);
  92             string json = ConvertJson(obj);
  93             return Do(db => db.StringSet(key,json,expiry));
  94         }
  95 
  96         /// <summary>
  97         /// 獲取單個key的值
  98         /// </summary>
  99         /// <param name="key">Redis Key</param>
 100         /// <returns></returns>
 101         public string StringGet(string key)
 102         {
 103             key = AddSysCustomKey(key);
 104             return Do(db => db.StringGet(key));
 105         }
 106 
 107         /// <summary>
 108         /// 獲取多個Key
 109         /// </summary>
 110         /// <param name="listKey">Redis Key集合</param>
 111         /// <returns></returns>
 112         public RedisValue[] StringGet(List<string> listKey)
 113         {
 114             List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();
 115             return Do(db => db.StringGet(ConvertRedisKeys(newKeys)));
 116         }
 117 
 118         /// <summary>
 119         /// 獲取一個key的物件
 120         /// </summary>
 121         /// <typeparam name="T"></typeparam>
 122         /// <param name="key"></param>
 123         /// <returns></returns>
 124         public T StringGet<T>(string key)
 125         {
 126             key = AddSysCustomKey(key);
 127             return Do(db => ConvertObj<T>(db.StringGet(key)));
 128         }
 129 
 130         /// <summary>
 131         /// 為數字增長val
 132         /// </summary>
 133         /// <param name="key"></param>
 134         /// <param name="val">可以為負</param>
 135         /// <returns>增長後的值</returns>
 136         public double StringIncrement(string key,double val = 1)
 137         {
 138             key = AddSysCustomKey(key);
 139             return Do(db => db.StringIncrement(key,val));
 140         }
 141 
 142         /// <summary>
 143         /// 為數字減少val
 144         /// </summary>
 145         /// <param name="key"></param>
 146         /// <param name="val">可以為負</param>
 147         /// <returns>減少後的值</returns>
 148         public double StringDecrement(string key,double val = 1)
 149         {
 150             key = AddSysCustomKey(key);
 151             return Do(db => db.StringDecrement(key,val));
 152         }
 153 
 154         #endregion 同步方法
 155 
 156         #region 非同步方法
 157 
 158         /// <summary>
 159         /// 儲存單個key value
 160         /// </summary>
 161         /// <param name="key">Redis Key</param>
 162         /// <param name="value">儲存的值</param>
 163         /// <param name="expiry">過期時間</param>
 164         /// <returns></returns>
 165         public async Task<bool> StringSetAsync(string key,TimeSpan? expiry = default(TimeSpan?))
 166         {
 167             key = AddSysCustomKey(key);
 168             return await Do(db => db.StringSetAsync(key,expiry));
 169         }
 170 
 171         /// <summary>
 172         /// 儲存多個key value
 173         /// </summary>
 174         /// <param name="keyValues">鍵值對</param>
 175         /// <returns></returns>
 176         public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey,RedisValue>> keyValues)
 177         {
 178             List<KeyValuePair<RedisKey,RedisValue>> newkeyValues =
 179                 keyValues.Select(p => new KeyValuePair<RedisKey,p.Value)).ToList();
 180             return await Do(db => db.StringSetAsync(newkeyValues.ToArray()));
 181         }
 182 
 183         /// <summary>
 184         /// 儲存一個物件
 185         /// </summary>
 186         /// <typeparam name="T"></typeparam>
 187         /// <param name="key"></param>
 188         /// <param name="obj"></param>
 189         /// <param name="expiry"></param>
 190         /// <returns></returns>
 191         public async Task<bool> StringSetAsync<T>(string key,TimeSpan? expiry = default(TimeSpan?))
 192         {
 193             key = AddSysCustomKey(key);
 194             string json = ConvertJson(obj);
 195             return await Do(db => db.StringSetAsync(key,expiry));
 196         }
 197 
 198         /// <summary>
 199         /// 獲取單個key的值
 200         /// </summary>
 201         /// <param name="key">Redis Key</param>
 202         /// <returns></returns>
 203         public async Task<string> StringGetAsync(string key)
 204         {
 205             key = AddSysCustomKey(key);
 206             return await Do(db => db.StringGetAsync(key));
 207         }
 208 
 209         /// <summary>
 210         /// 獲取多個Key
 211         /// </summary>
 212         /// <param name="listKey">Redis Key集合</param>
 213         /// <returns></returns>
 214         public async Task<RedisValue[]> StringGetAsync(List<string> listKey)
 215         {
 216             List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();
 217             return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys)));
 218         }
 219 
 220         /// <summary>
 221         /// 獲取一個key的物件
 222         /// </summary>
 223         /// <typeparam name="T"></typeparam>
 224         /// <param name="key"></param>
 225         /// <returns></returns>
 226         public async Task<T> StringGetAsync<T>(string key)
 227         {
 228             key = AddSysCustomKey(key);
 229             string result = await Do(db => db.StringGetAsync(key));
 230             return ConvertObj<T>(result);
 231         }
 232 
 233         /// <summary>
 234         /// 為數字增長val
 235         /// </summary>
 236         /// <param name="key"></param>
 237         /// <param name="val">可以為負</param>
 238         /// <returns>增長後的值</returns>
 239         public async Task<double> StringIncrementAsync(string key,double val = 1)
 240         {
 241             key = AddSysCustomKey(key);
 242             return await Do(db => db.StringIncrementAsync(key,val));
 243         }
 244 
 245         /// <summary>
 246         /// 為數字減少val
 247         /// </summary>
 248         /// <param name="key"></param>
 249         /// <param name="val">可以為負</param>
 250         /// <returns>減少後的值</returns>
 251         public async Task<double> StringDecrementAsync(string key,double val = 1)
 252         {
 253             key = AddSysCustomKey(key);
 254             return await Do(db => db.StringDecrementAsync(key,val));
 255         }
 256 
 257         #endregion 非同步方法
 258 
 259         #endregion String
 260 
 261         #region Hash
 262 
 263         #region 同步方法
 264 
 265         /// <summary>
 266         /// 判斷某個資料是否已經被快取
 267         /// </summary>
 268         /// <param name="key"></param>
 269         /// <param name="dataKey"></param>
 270         /// <returns></returns>
 271         public bool HashExists(string key,string dataKey)
 272         {
 273             key = AddSysCustomKey(key);
 274             return Do(db => db.HashExists(key,dataKey));
 275         }
 276 
 277         /// <summary>
 278         /// 儲存資料到hash表
 279         /// </summary>
 280         /// <typeparam name="T"></typeparam>
 281         /// <param name="key"></param>
 282         /// <param name="dataKey"></param>
 283         /// <param name="t"></param>
 284         /// <returns></returns>
 285         public bool HashSet<T>(string key,string dataKey,T t)
 286         {
 287             key = AddSysCustomKey(key);
 288             return Do(db =>
 289             {
 290                 string json = ConvertJson(t);
 291                 return db.HashSet(key,dataKey,json);
 292             });
 293         }
 294 
 295         /// <summary>
 296         /// 移除hash中的某值
 297         /// </summary>
 298         /// <param name="key"></param>
 299         /// <param name="dataKey"></param>
 300         /// <returns></returns>
 301         public bool HashDelete(string key,string dataKey)
 302         {
 303             key = AddSysCustomKey(key);
 304             return Do(db => db.HashDelete(key,dataKey));
 305         }
 306 
 307         /// <summary>
 308         /// 移除hash中的多個值
 309         /// </summary>
 310         /// <param name="key"></param>
 311         /// <param name="dataKeys"></param>
 312         /// <returns></returns>
 313         public long HashDelete(string key,List<RedisValue> dataKeys)
 314         {
 315             key = AddSysCustomKey(key);
 316             return Do(db => db.HashDelete(key,dataKeys.ToArray()));
 317         }
 318 
 319         /// <summary>
 320         /// 從hash表獲取資料
 321         /// </summary>
 322         /// <typeparam name="T"></typeparam>
 323         /// <param name="key"></param>
 324         /// <param name="dataKey"></param>
 325         /// <returns></returns>
 326         public T HashGet<T>(string key,string dataKey)
 327         {
 328             key = AddSysCustomKey(key);
 329             return Do(db =>
 330             {
 331                 string value = db.HashGet(key,dataKey);
 332                 return ConvertObj<T>(value);
 333             });
 334         }
 335 
 336         /// <summary>
 337         /// 從hash表獲取資料
 338         /// </summary>
 339         /// <typeparam name="T"></typeparam>
 340         /// <param name="key"></param>
 341         /// <param name="dataKey"></param>
 342         /// <returns></returns>
 343         public string HashGetString(string key,string dataKey)
 344         {
 345             key = AddSysCustomKey(key);
 346             return Do(db =>
 347             {
 348                 return db.HashGet(key,dataKey);
 349             });
 350         }
 351 
 352         /// <summary>
 353         /// 為數字增長val
 354         /// </summary>
 355         /// <param name="key"></param>
 356         /// <param name="dataKey"></param>
 357         /// <param name="val">可以為負</param>
 358         /// <returns>增長後的值</returns>
 359         public double HashIncrement(string key,string dataKey,double val = 1)
 360         {
 361             key = AddSysCustomKey(key);
 362             return Do(db => db.HashIncrement(key,val));
 363         }
 364 
 365         /// <summary>
 366         /// 為數字減少val
 367         /// </summary>
 368         /// <param name="key"></param>
 369         /// <param name="dataKey"></param>
 370         /// <param name="val">可以為負</param>
 371         /// <returns>減少後的值</returns>
 372         public double HashDecrement(string key,double val = 1)
 373         {
 374             key = AddSysCustomKey(key);
 375             return Do(db => db.HashDecrement(key,val));
 376         }
 377 
 378         /// <summary>
 379         /// 獲取hashkey所有Redis key
 380         /// </summary>
 381         /// <typeparam name="T"></typeparam>
 382         /// <param name="key"></param>
 383         /// <returns></returns>
 384         public List<T> HashKeys<T>(string key)
 385         {
 386             key = AddSysCustomKey(key);
 387             return Do(db =>
 388             {
 389                 RedisValue[] values = db.HashKeys(key);
 390                 return ConvetList<T>(values);
 391             });
 392         }
 393 
 394         public List<string> HashKeysString<T>(string key)
 395         {
 396             key = AddSysCustomKey(key);
 397             return Do<List<string>>(db => this.ConvertString<string>(db.HashKeys(key,CommandFlags.None)));
 398         }
 399 
 400         #endregion 同步方法
 401 
 402         #region 非同步方法
 403 
 404         /// <summary>
 405         /// 判斷某個資料是否已經被快取
 406         /// </summary>
 407         /// <param name="key"></param>
 408         /// <param name="dataKey"></param>
 409         /// <returns></returns>
 410         public async Task<bool> HashExistsAsync(string key,string dataKey)
 411         {
 412             key = AddSysCustomKey(key);
 413             return await Do(db => db.HashExistsAsync(key,dataKey));
 414         }
 415 
 416         /// <summary>
 417         /// 儲存資料到hash表
 418         /// </summary>
 419         /// <typeparam name="T"></typeparam>
 420         /// <param name="key"></param>
 421         /// <param name="dataKey"></param>
 422         /// <param name="t"></param>
 423         /// <returns></returns>
 424         public async Task<bool> HashSetAsync<T>(string key,T t)
 425         {
 426             key = AddSysCustomKey(key);
 427             return await Do(db =>
 428             {
 429                 string json = ConvertJson(t);
 430                 return db.HashSetAsync(key,json);
 431             });
 432         }
 433 
 434         /// <summary>
 435         /// 移除hash中的某值
 436         /// </summary>
 437         /// <param name="key"></param>
 438         /// <param name="dataKey"></param>
 439         /// <returns></returns>
 440         public async Task<bool> HashDeleteAsync(string key,string dataKey)
 441         {
 442             key = AddSysCustomKey(key);
 443             return await Do(db => db.HashDeleteAsync(key,dataKey));
 444         }
 445 
 446         /// <summary>
 447         /// 移除hash中的多個值
 448         /// </summary>
 449         /// <param name="key"></param>
 450         /// <param name="dataKeys"></param>
 451         /// <returns></returns>
 452         public async Task<long> HashDeleteAsync(string key,List<RedisValue> dataKeys)
 453         {
 454             key = AddSysCustomKey(key);
 455             //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};
 456             return await Do(db => db.HashDeleteAsync(key,dataKeys.ToArray()));
 457         }
 458 
 459         /// <summary>
 460         /// 從hash表獲取資料
 461         /// </summary>
 462         /// <typeparam name="T"></typeparam>
 463         /// <param name="key"></param>
 464         /// <param name="dataKey"></param>
 465         /// <returns></returns>
 466         public async Task<T> HashGeAsync<T>(string key,string dataKey)
 467         {
 468             key = AddSysCustomKey(key);
 469             string value = await Do(db => db.HashGetAsync(key,dataKey));
 470             return ConvertObj<T>(value);
 471         }
 472 
 473         /// <summary>
 474         /// 為數字增長val
 475         /// </summary>
 476         /// <param name="key"></param>
 477         /// <param name="dataKey"></param>
 478         /// <param name="val">可以為負</param>
 479         /// <returns>增長後的值</returns>
 480         public async Task<double> HashIncrementAsync(string key,double val = 1)
 481         {
 482             key = AddSysCustomKey(key);
 483             return await Do(db => db.HashIncrementAsync(key,val));
 484         }
 485 
 486         /// <summary>
 487         /// 為數字減少val
 488         /// </summary>
 489         /// <param name="key"></param>
 490         /// <param name="dataKey"></param>
 491         /// <param name="val">可以為負</param>
 492         /// <returns>減少後的值</returns>
 493         public async Task<double> HashDecrementAsync(string key,double val = 1)
 494         {
 495             key = AddSysCustomKey(key);
 496             return await Do(db => db.HashDecrementAsync(key,val));
 497         }
 498 
 499         /// <summary>
 500         /// 獲取hashkey所有Redis key
 501         /// </summary>
 502         /// <typeparam name="T"></typeparam>
 503         /// <param name="key"></param>
 504         /// <returns></returns>
 505         public async Task<List<T>> HashKeysAsync<T>(string key)
 506         {
 507             key = AddSysCustomKey(key);
 508             RedisValue[] values = await Do(db => db.HashKeysAsync(key));
 509             return ConvetList<T>(values);
 510         }
 511 
 512         #endregion 非同步方法
 513 
 514         #endregion Hash
 515 
 516         #region List
 517 
 518         #region 同步方法
 519 
 520         /// <summary>
 521         /// 移除指定ListId的內部List的值
 522         /// </summary>
 523         /// <param name="key"></param>
 524         /// <param name="value"></param>
 525         public void ListRemove<T>(string key,T value)
 526         {
 527             key = AddSysCustomKey(key);
 528             Do(db => db.ListRemove(key,ConvertJson(value)));
 529         }
 530 
 531         /// <summary>
 532         /// 獲取指定key的List
 533         /// </summary>
 534         /// <param name="key"></param>
 535         /// <returns></returns>
 536         public List<T> ListRange<T>(string key)
 537         {
 538             key = AddSysCustomKey(key);
 539             return Do(redis =>
 540             {
 541                 var values = redis.ListRange(key);
 542                 return ConvetList<T>(values);
 543             });
 544         }
 545 
 546         /// <summary>
 547         /// 入隊
 548         /// </summary>
 549         /// <param name="key"></param>
 550         /// <param name="value"></param>
 551         public void ListRightPush<T>(string key,T value)
 552         {
 553             key = AddSysCustomKey(key);
 554             Do(db => db.ListRightPush(key,ConvertJson(value)));
 555         }
 556 
 557         /// <summary>
 558         /// 出隊
 559         /// </summary>
 560         /// <typeparam name="T"></typeparam>
 561         /// <param name="key"></param>
 562         /// <returns></returns>
 563         public T ListRightPop<T>(string key)
 564         {
 565             key = AddSysCustomKey(key);
 566             return Do(db =>
 567             {
 568                 var value = db.ListRightPop(key);
 569                 return ConvertObj<T>(value);
 570             });
 571         }
 572 
 573         /// <summary>
 574         /// 入棧
 575         /// </summary>
 576         /// <typeparam name="T"></typeparam>
 577         /// <param name="key"></param>
 578         /// <param name="value"></param>
 579         public void ListLeftPush<T>(string key,T value)
 580         {
 581             key = AddSysCustomKey(key);
 582             Do(db => db.ListLeftPush(key,ConvertJson(value)));
 583         }
 584 
 585         /// <summary>
 586         /// 出棧
 587         /// </summary>
 588         /// <typeparam name="T"></typeparam>
 589         /// <param name="key"></param>
 590         /// <returns></returns>
 591         public T ListLeftPop<T>(string key)
 592         {
 593             key = AddSysCustomKey(key);
 594             return Do(db =>
 595             {
 596                 var value = db.ListLeftPop(key);
 597                 return ConvertObj<T>(value);
 598             });
 599         }
 600 
 601         /// <summary>
 602         /// 出棧
 603         /// </summary>
 604         /// <typeparam name="T"></typeparam>
 605         /// <param name="key"></param>
 606         /// <returns></returns>
 607         public string ListLeftPopString(string key)
 608         {
 609             key = AddSysCustomKey(key);
 610             return Do(db =>
 611             {
 612                 return db.ListLeftPop(key);
 613             });
 614         }
 615 
 616         /// <summary>
 617         /// 獲取集合中的數量
 618         /// </summary>
 619         /// <param name="key"></param>
 620         /// <returns></returns>
 621         public long ListLength(string key)
 622         {
 623             key = AddSysCustomKey(key);
 624             return Do(redis => redis.ListLength(key));
 625         }
 626 
 627         #endregion 同步方法
 628 
 629         #region 非同步方法
 630 
 631         /// <summary>
 632         /// 移除指定ListId的內部List的值
 633         /// </summary>
 634         /// <param name="key"></param>
 635         /// <param name="value"></param>
 636         public async Task<long> ListRemoveAsync<T>(string key,T value)
 637         {
 638             key = AddSysCustomKey(key);
 639             return await Do(db => db.ListRemoveAsync(key,ConvertJson(value)));
 640         }
 641 
 642         /// <summary>
 643         /// 獲取指定key的List
 644         /// </summary>
 645         /// <param name="key"></param>
 646         /// <returns></returns>
 647         public async Task<List<T>> ListRangeAsync<T>(string key)
 648         {
 649             key = AddSysCustomKey(key);
 650             var values = await Do(redis => redis.ListRangeAsync(key));
 651             return ConvetList<T>(values);
 652         }
 653 
 654         /// <summary>
 655         /// 入隊
 656         /// </summary>
 657         /// <param name="key"></param>
 658         /// <param name="value"></param>
 659         public async Task<long> ListRightPushAsync<T>(string key,T value)
 660         {
 661             key = AddSysCustomKey(key);
 662             return await Do(db => db.ListRightPushAsync(key,ConvertJson(value)));
 663         }
 664 
 665         /// <summary>
 666         /// 出隊
 667         /// </summary>
 668         /// <typeparam name="T"></typeparam>
 669         /// <param name="key"></param>
 670         /// <returns></returns>
 671         public async Task<T> ListRightPopAsync<T>(string key)
 672         {
 673             key = AddSysCustomKey(key);
 674             var value = await Do(db => db.ListRightPopAsync(key));
 675             return ConvertObj<T>(value);
 676         }
 677 
 678         /// <summary>
 679         /// 入棧
 680         /// </summary>
 681         /// <typeparam name="T"></typeparam>
 682         /// <param name="key"></param>
 683         /// <param name="value"></param>
 684         public async Task<long> ListLeftPushAsync<T>(string key,T value)
 685         {
 686             key = AddSysCustomKey(key);
 687             return await Do(db => db.ListLeftPushAsync(key,ConvertJson(value)));
 688         }
 689 
 690         /// <summary>
 691         /// 出棧
 692         /// </summary>
 693         /// <typeparam name="T"></typeparam>
 694         /// <param name="key"></param>
 695         /// <returns></returns>
 696         public async Task<T> ListLeftPopAsync<T>(string key)
 697         {
 698             key = AddSysCustomKey(key);
 699             var value = await Do(db => db.ListLeftPopAsync(key));
 700             return ConvertObj<T>(value);
 701         }
 702 
 703         /// <summary>
 704         /// 獲取集合中的數量
 705         /// </summary>
 706         /// <param name="key"></param>
 707         /// <returns></returns>
 708         public async Task<long> ListLengthAsync(string key)
 709         {
 710             key = AddSysCustomKey(key);
 711             return await Do(redis => redis.ListLengthAsync(key));
 712         }
 713 
 714         #endregion 非同步方法
 715 
 716         #endregion List
 717 
 718         #region SortedSet 有序集合
 719 
 720         #region 同步方法
 721 
 722         /// <summary>
 723         /// 新增
 724         /// </summary>
 725         /// <param name="key"></param>
 726         /// <param name="value"></param>
 727         /// <param name="score"></param>
 728         public bool SortedSetAdd<T>(string key,T value,double score)
 729         {
 730             key = AddSysCustomKey(key);
 731             return Do(redis => redis.SortedSetAdd(key,ConvertJson<T>(value),score));
 732         }
 733 
 734         /// <summary>
 735         /// 刪除
 736         /// </summary>
 737         /// <param name="key"></param>
 738         /// <param name="value"></param>
 739         public bool SortedSetRemove<T>(string key,T value)
 740         {
 741             key = AddSysCustomKey(key);
 742             return Do(redis => redis.SortedSetRemove(key,ConvertJson(value)));
 743         }
 744 
 745         /// <summary>
 746         /// 獲取全部
 747         /// </summary>
 748         /// <param name="key"></param>
 749         /// <returns></returns>
 750         public List<T> SortedSetRangeByRank<T>(string key)
 751         {
 752             key = AddSysCustomKey(key);
 753             return Do(redis =>
 754             {
 755                 var values = redis.SortedSetRangeByRank(key);
 756                 return ConvetList<T>(values);
 757             });
 758         }
 759 
 760         /// <summary>
 761         /// 獲取集合中的數量
 762         /// </summary>
 763         /// <param name="key"></param>
 764         /// <returns></returns>
 765         public long SortedSetLength(string key)
 766         {
 767             key = AddSysCustomKey(key);
 768             return Do(redis => redis.SortedSetLength(key));
 769         }
 770 
 771         #endregion 同步方法
 772 
 773         #region 非同步方法
 774 
 775         /// <summary>
 776         /// 新增
 777         /// </summary>
 778         /// <param name="key"></param>
 779         /// <param name="value"></param>
 780         /// <param name="score"></param>
 781         public async Task<bool> SortedSetAddAsync<T>(string key,double score)
 782         {
 783             key = AddSysCustomKey(key);
 784             return await Do(redis => redis.SortedSetAddAsync(key,score));
 785         }
 786 
 787         /// <summary>
 788         /// 刪除
 789         /// </summary>
 790         /// <param name="key"></param>
 791         /// <param name="value"></param>
 792         public async Task<bool> SortedSetRemoveAsync<T>(string key,T value)
 793         {
 794             key = AddSysCustomKey(key);
 795             return await Do(redis => redis.SortedSetRemoveAsync(key,ConvertJson(value)));
 796         }
 797 
 798         /// <summary>
 799         /// 獲取全部
 800         /// </summary>
 801         /// <param name="key"></param>
 802         /// <returns></returns>
 803         public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key)
 804         {
 805             key = AddSysCustomKey(key);
 806             var values = await Do(redis => redis.SortedSetRangeByRankAsync(key));
 807             return ConvetList<T>(values);
 808         }
 809 
 810         /// <summary>
 811         /// 獲取集合中的數量
 812         /// </summary>
 813         /// <param name="key"></param>
 814         /// <returns></returns>
 815         public async Task<long> SortedSetLengthAsync(string key)
 816         {
 817             key = AddSysCustomKey(key);
 818             return await Do(redis => redis.SortedSetLengthAsync(key));
 819         }
 820 
 821         #endregion 非同步方法
 822 
 823         #endregion SortedSet 有序集合
 824 
 825         #region key
 826 
 827         /// <summary>
 828         /// 刪除單個key
 829         /// </summary>
 830         /// <param name="key">redis key</param>
 831         /// <returns>是否刪除成功</returns>
 832         public bool KeyDelete(string key)
 833         {
 834             key = AddSysCustomKey(key);
 835             return Do(db => db.KeyDelete(key));
 836         }
 837 
 838         /// <summary>
 839         /// 刪除多個key
 840         /// </summary>
 841         /// <param name="keys">rediskey</param>
 842         /// <returns>成功刪除的個數</returns>
 843         public long KeyDelete(List<string> keys)
 844         {
 845             List<string> newKeys = keys.Select(AddSysCustomKey).ToList();
 846             return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys)));
 847         }
 848 
 849         /// <summary>
 850         /// 判斷key是否儲存
 851         /// </summary>
 852         /// <param name="key">redis key</param>
 853         /// <returns></returns>
 854         public bool KeyExists(string key)
 855         {
 856             key = AddSysCustomKey(key);
 857             return Do(db => db.KeyExists(key));
 858         }
 859 
 860         /// <summary>
 861         /// 重新命名key
 862         /// </summary>
 863         /// <param name="key">就的redis key</param>
 864         /// <param name="newKey">新的redis key</param>
 865         /// <returns></returns>
 866         public bool KeyRename(string key,string newKey)
 867         {
 868             key = AddSysCustomKey(key);
 869             return Do(db => db.KeyRename(key,newKey));
 870         }
 871 
 872         /// <summary>
 873         /// 設定Key的時間
 874         /// </summary>
 875         /// <param name="key">redis key</param>
 876         /// <param name="expiry"></param>
 877         /// <returns></returns>
 878         public bool KeyExpire(string key,TimeSpan? expiry = default(TimeSpan?))
 879         {
 880             key = AddSysCustomKey(key);
 881             return Do(db => db.KeyExpire(key,expiry));
 882         }
 883 
 884         #endregion key
 885 
 886         #region 釋出訂閱
 887 
 888         /// <summary>
 889         /// Redis釋出訂閱  訂閱
 890         /// </summary>
 891         /// <param name="subChannel"></param>
 892         /// <param name="handler"></param>
 893         public void Subscribe(string subChannel,Action<RedisChannel,RedisValue> handler = null)
 894         {
 895             ISubscriber sub = _conn.GetSubscriber();
 896             sub.Subscribe(subChannel,(channel,message) =>
 897             {
 898                 if (handler == null)
 899                 {
 900                     Console.WriteLine(subChannel + " 訂閱收到訊息:" + message);
 901                 }
 902                 else
 903                 {
 904                     handler(channel,message);
 905                 }
 906             });
 907         }
 908 
 909         /// <summary>
 910         /// Redis釋出訂閱  釋出
 911         /// </summary>
 912         /// <typeparam name="T"></typeparam>
 913         /// <param name="channel"></param>
 914         /// <param name="msg"></param>
 915         /// <returns></returns>
 916         public long Publish<T>(string channel,T msg)
 917         {
 918             ISubscriber sub = _conn.GetSubscriber();
 919             return sub.Publish(channel,ConvertJson(msg));
 920         }
 921 
 922         /// <summary>
 923         /// Redis釋出訂閱  取消訂閱
 924         /// </summary>
 925         /// <param name="channel"></param>
 926         public void Unsubscribe(string channel)
 927         {
 928             ISubscriber sub = _conn.GetSubscriber();
 929             sub.Unsubscribe(channel);
 930         }
 931 
 932         /// <summary>
 933         /// Redis釋出訂閱  取消全部訂閱
 934         /// </summary>
 935         public void UnsubscribeAll()
 936         {
 937             ISubscriber sub = _conn.GetSubscriber();
 938             sub.UnsubscribeAll();
 939         }
 940 
 941         #endregion 釋出訂閱
 942 
 943         #region 其他
 944 
 945         public ITransaction CreateTransaction()
 946         {
 947             return GetDatabase().CreateTransaction();
 948         }
 949 
 950         public IDatabase GetDatabase()
 951         {
 952             return _conn.GetDatabase(DbNum);
 953         }
 954 
 955         public IServer GetServer(string hostAndPort)
 956         {
 957             return _conn.GetServer(hostAndPort);
 958         }
 959 
 960         /// <summary>
 961         /// 設定字首
 962         /// </summary>
 963         /// <param name="customKey"></param>
 964         public void SetSysCustomKey(string customKey)
 965         {
 966             CustomKey = customKey;
 967         }
 968 
 969         /// <summary>
 970         /// 刪除集合
 971         /// </summary>
 972         /// <param name="redisKey"></param>
 973         /// <param name="databaseNum"></param>
 974         /// <returns></returns>
 975         public bool KeyRemove(string redisKey)
 976         {
 977             var database = _conn.GetDatabase(DbNum);
 978             return database.KeyDelete(redisKey);
 979         }
 980 
 981         #endregion 其他
 982 
 983         #region 輔助方法
 984 
 985         private string AddSysCustomKey(string oldKey)
 986         {
 987             var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey;
 988             return prefixKey + oldKey;
 989         }
 990 
 991         private T Do<T>(Func<IDatabase,T> func)
 992         {
 993             var database = _conn.GetDatabase(DbNum);
 994             return func(database);
 995         }
 996 
 997         private string ConvertJson<T>(T value)
 998         {
 999             string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value);
1000             return result;
1001         }
1002 
1003         private T ConvertObj<T>(RedisValue value)
1004         {
1005             if (value.IsNull)
1006                 return default(T);
1007             return JsonConvert.DeserializeObject<T>(value);
1008         }
1009 
1010         private List<T> ConvetList<T>(RedisValue[] values)
1011         {
1012             if (values == null)
1013                 return null;
1014 
1015             List<T> result = new List<T>();
1016             foreach (var item in values)
1017             {
1018                 var model = ConvertObj<T>(item);
1019                 result.Add(model);
1020             }
1021             return result;
1022         }
1023 
1024         private List<string> ConvertString<T>(RedisValue[] values)
1025         {
1026             List<string> list = new List<string>();
1027             if (values == null)
1028             {
1029                 return null;
1030             }
1031             foreach (RedisValue value2 in values)
1032             {
1033                 list.Add(value2.ToString());
1034             }
1035             return list;
1036         }
1037 
1038         private RedisKey[] ConvertRedisKeys(List<string> redisKeys)
1039         {
1040             return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray();
1041         }
1042 
1043         #endregion 輔助方法
1044     }
View Code

  測試中用到的HashSet和Get方法,其他的使用到的可以測試下,

1         public bool HashSet<T>(string key,T t)
2         {
3             key = AddSysCustomKey(key);
4             return Do(db =>
5             {
6                 string json = ConvertJson(t);
7                 return db.HashSet(key,json);
8             });
9         }

  Main函式中的測試用例,也只是簡單測試了下,

 1             string key = "123456";
 2             string dataKey = "123456";
 3 
 4             redisHelper.HashSet(key,"123456");
 5 
 6             string x = redisHelper.HashGetString(key,dataKey);
 7             Console.WriteLine("x = {0}",x);
 8 
 9 
10             Student student = new Student { Age = 11,Name = "Jack" };
11             redisHelper = new RedisHelper(1);
12             redisHelper.HashSet(key,student);
13 
14             Student getStu = redisHelper.HashGet<Student>(key,dataKey);
15             if(getStu != null)
16             {
17                 Console.WriteLine("Name = {0},Age = {1}.",getStu.Name,getStu.Age);
18             }
19             else
20             {
21                 Console.WriteLine("Get student failure.");
22             }

  輸出結果:

技術分享圖片

  檢視Redis快取中儲存的資料,使用Redis客戶端進行檢視,因為程式碼中間redisHelper進行了重新構造,所以下圖會在兩個DB中。

技術分享圖片

技術分享圖片

  Redis中值(value)可以是 字串(String),雜湊(Hash),列表(list),集合(sets) 和 有序集合(sorted sets)等型別。

 測試下,佇列在Redis中的應用,入隊(左進右出,右進左出都有,組合就是棧和佇列啦),redisHelper.ListRightPush("PushTest",student);

 再用Redis客戶端檢視,與用Hash儲存的不一樣,Redis佇列也可以放心使用,日活百萬以下沒什麼問題,再往上考慮Kafka呀,

技術分享圖片

  使用ListLeftPop,右進左出的佇列,程式碼:

 1             Console.WriteLine("0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0");
 2 
 3             for(int i = 0; i < 3; i++)
 4             {
 5                 student = new Student { Age = 11 + i,Name = string.Format("Jack {0}",i) };
 6                 redisHelper.ListRightPush("PushTest",student);
 7             }
 8 
 9             getStu = redisHelper.ListLeftPop<Student>("PushTest");
10             while (getStu != null)
11             {
12                 Console.WriteLine("Name = {0},getStu.Age);
13                 getStu = redisHelper.ListLeftPop<Student>("PushTest");
14             }

  執行輸出,前兩個是剛才執行入隊一個,現在執行一次程式又入隊一個,所以,取出五個,與放入順序一致,先進先出。

技術分享圖片