隐藏

C#中使用Redis的五大数据结构相关操作及应用场景

发布:2023/3/30 15:30:54作者:管理员 来源:本站 浏览次数:623

Cache和NoSql、Redis














ServiceStack.Redis




下面额代码类均是通过 ServiceStack.Redis 来对Redis进行各种操作




redis 文件配置类


复制代码




   /// <summary>


   /// redis配置文件信息


   /// 也可以放到配置文件去


   /// </summary>


   public sealed class RedisConfigInfo


   {


       /// <summary>


       /// 可写的Redis链接地址


       /// format:ip1,ip2


       ///


       /// 默认6379端口


       /// </summary>


       public string WriteServerList = "127.0.0.1:6379";


       /// <summary>


       /// 可读的Redis链接地址


       /// format:ip1,ip2


       /// </summary>


       public string ReadServerList = "127.0.0.1:6379";


       /// <summary>


       /// 最大写链接数


       /// </summary>


       public int MaxWritePoolSize = 60;


       /// <summary>


       /// 最大读链接数


       /// </summary>


       public int MaxReadPoolSize = 60;


       /// <summary>


       /// 本地缓存到期时间,单位:秒


       /// </summary>


       public int LocalCacheTime = 180;


       /// <summary>


       /// 自动重启


       /// </summary>


       public bool AutoStart = true;


       /// <summary>


       /// 是否记录日志,该设置仅用于排查redis运行时出现的问题,


       /// 如redis工作正常,请关闭该项


       /// </summary>


       public bool RecordeLog = false;


   }




复制代码




redis操作的基类


复制代码




/// <summary>


   /// RedisBase类,是redis操作的基类,继承自IDisposable接口,主要用于释放内存


   /// </summary>


   public abstract class RedisBase : IDisposable


   {


       public IRedisClient iClient { get; private set; }


       /// <summary>


       /// 构造时完成链接的打开


       /// </summary>


       public RedisBase()


       {


           iClient = RedisManager.GetClient();


       }




       //public static IRedisClient iClient { get; private set; }


       //static RedisBase()


       //{


       //    iClient = RedisManager.GetClient();


       //}






       private bool _disposed = false;


       protected virtual void Dispose(bool disposing)


       {


           if (!this._disposed)


           {


               if (disposing)


               {


                   iClient.Dispose();


                   iClient = null;


               }


           }


           this._disposed = true;


       }


       public void Dispose()


       {


           Dispose(true);


           GC.SuppressFinalize(this);


       }




       public void Transcation()


       {


           using (IRedisTransaction irt = this.iClient.CreateTransaction())


           {


               try


               {


                   irt.QueueCommand(r => r.Set("key", 20));


                   irt.QueueCommand(r => r.Increment("key", 1));


                   irt.Commit(); // 提交事务


               }


               catch (Exception ex)


               {


                   irt.Rollback();


                   throw ex;


               }


           }


       }






       /// <summary>


       /// 清除全部数据 请小心


       /// </summary>


       public virtual void FlushAll()


       {


           iClient.FlushAll();


       }




       /// <summary>


       /// 保存数据DB文件到硬盘


       /// </summary>


       public void Save()


       {


           iClient.Save();//阻塞式save


       }




       /// <summary>


       /// 异步保存数据DB文件到硬盘


       /// </summary>


       public void SaveAsync()


       {


           iClient.SaveAsync();//异步save


       }


   }




复制代码




Redis管理中心


复制代码




/// <summary>


   /// Redis管理中心


   /// </summary>


   public class RedisManager


   {


       /// <summary>


       /// redis配置文件信息


       /// </summary>


       private static RedisConfigInfo RedisConfigInfo = new RedisConfigInfo();




       /// <summary>


       /// Redis客户端池化管理


       /// </summary>


       private static PooledRedisClientManager prcManager;




       /// <summary>


       /// 静态构造方法,初始化链接池管理对象


       /// </summary>


       static RedisManager()


       {


           CreateManager();


       }




       /// <summary>


       /// 创建链接池管理对象


       /// </summary>


       private static void CreateManager()


       {


           string[] WriteServerConStr = RedisConfigInfo.WriteServerList.Split(',');


           string[] ReadServerConStr = RedisConfigInfo.ReadServerList.Split(',');


           prcManager = new PooledRedisClientManager(ReadServerConStr, WriteServerConStr,


                            new RedisClientManagerConfig


                            {


                                MaxWritePoolSize = RedisConfigInfo.MaxWritePoolSize,


                                MaxReadPoolSize = RedisConfigInfo.MaxReadPoolSize,


                                AutoStart = RedisConfigInfo.AutoStart,


                            });


       }




       /// <summary>


       /// 客户端缓存操作对象


       /// </summary>


       public static IRedisClient GetClient()


       {


           return prcManager.GetClient();


       }


   }




复制代码


String








redis 的string类型操作类


复制代码




   /// <summary>


   /// key-value 键值对:value可以是序列化的数据


   /// </summary>


   public class RedisStringService : RedisBase


   {


       #region 赋值


       /// <summary>


       /// 设置key的value


       /// </summary>


       public bool Set<T>(string key, T value)


       {


           return base.iClient.Set<T>(key, value);


       }


       /// <summary>


       /// 设置key的value并设置过期时间


       /// </summary>


       public bool Set<T>(string key, T value, DateTime dt)


       {


           return base.iClient.Set<T>(key, value, dt);


       }


       /// <summary>


       /// 设置key的value并设置过期时间


       /// </summary>


       public bool Set<T>(string key, T value, TimeSpan sp)


       {


           return base.iClient.Set<T>(key, value, sp);


       }


       /// <summary>


       /// 设置多个key/value


       /// </summary>


       public void Set(Dictionary<string, string> dic)


       {


           base.iClient.SetAll(dic);


       }




       #endregion




       #region 追加


       /// <summary>


       /// 在原有key的value值之后追加value,没有就新增一项


       /// </summary>


       public long Append(string key, string value)


       {


           return base.iClient.AppendToValue(key, value);


       }


       #endregion




       #region 获取值


       /// <summary>


       /// 获取key的value值


       /// </summary>


       public string Get(string key)


       {


           return base.iClient.GetValue(key);


       }


       /// <summary>


       /// 获取多个key的value值


       /// </summary>


       public List<string> Get(List<string> keys)


       {


           return base.iClient.GetValues(keys);


       }


       /// <summary>


       /// 获取多个key的value值


       /// </summary>


       public List<T> Get<T>(List<string> keys)


       {


           return base.iClient.GetValues<T>(keys);


       }


       #endregion




       #region 获取旧值赋上新值


       /// <summary>


       /// 获取旧值赋上新值


       /// </summary>


       public string GetAndSetValue(string key, string value)


       {


           return base.iClient.GetAndSetValue(key, value);


       }


       #endregion




       #region 辅助方法


       /// <summary>


       /// 获取值的长度


       /// </summary>


       public long GetLength(string key)


       {


           return base.iClient.GetStringCount(key);


       }


       /// <summary>


       /// 自增1,返回自增后的值


       /// </summary>


       public long Incr(string key)


       {


           return base.iClient.IncrementValue(key);


       }


       /// <summary>


       /// 自增count,返回自增后的值


       /// </summary>


       public long IncrBy(string key, int count)


       {


           return base.iClient.IncrementValueBy(key, count);


       }


       /// <summary>


       /// 自减1,返回自减后的值


       /// </summary>


       public long Decr(string key)


       {


           return base.iClient.DecrementValue(key);


       }


       /// <summary>


       /// 自减count ,返回自减后的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="count"></param>


       /// <returns></returns>


       public long DecrBy(string key, int count)


       {


           return base.iClient.DecrementValueBy(key, count);


       }


       #endregion


   }




复制代码




使用


复制代码




               using (RedisStringService service = new RedisStringService())


               {


                   service.Set<string>("student1", "梦的翅膀");


                   Console.WriteLine(service.Get("student1"));




                   service.Append("student1", "20180802");


                   Console.WriteLine(service.Get("student1"));




                   Console.WriteLine(service.GetAndSetValue("student1", "程序错误"));


                   Console.WriteLine(service.Get("student1"));




                   service.Set<string>("student2", "王", DateTime.Now.AddSeconds(5));


                   Thread.Sleep(5100);


                   Console.WriteLine(service.Get("student2"));




                   service.Set<int>("Age", 32);


                   Console.WriteLine(service.Incr("Age"));


                   Console.WriteLine(service.IncrBy("Age", 3));


                   Console.WriteLine(service.Decr("Age"));


                   Console.WriteLine(service.DecrBy("Age", 3));


               }




复制代码




超卖






/// <summary>


/// 超卖:订单数超过商品


///


///数据库:秒杀的时候,10件商品,100个人想买,假定大家一瞬间都来了,


///A 查询还有没有--有---1更新


///B 查询还有没有--有---1更新


///C 查询还有没有--有---1更新


///可能会卖出12  12甚至20件商品


///


/// 微服务也有超卖的问题,异步队列


///


///


/// Redis原子性操作--保证一个数值只出现一次--防止一个商品卖给多个人


///


///


/// Redis是单线程,程序怎么又多线程操作Redis呢? 这个是可以的,


/// 打开多个链接,去提交任务,对程序而言,Redis是并发


///


/// 假如redis命令是拼装的,Decr---1 获取值  2 程序减1  3 再save结果回去


///     程序多线程并发一下,  A线程  1   2   3     初始值是10


///                           B线程    1 2 3       结果是9,减了2次但是结果是9


///                          


///     组合命令,Decr  Redis线程直接完成当前值-1并返回结果,原子性操作                    


///       程序多线程并发一下,A线程     123        初始值10


///                           B线程  123      


///                           C线程        123      得到3个结果,9/8/7


///


/// 假如库存只有1个(数据库),三个人同时来下单,一检测>0,都会成功--超卖


///                          三个人同时来,lock/开启事务


///                          只有一个人能去检测>0    -1  save


///                          然后第二个人来,==0 返回失败


///                          然后第三个人来,==0 返回失败


///     因为这个等于是数据库单线程了,其他都要阻塞,各种超时


///     -1的时候除了操作库存,还得增加订单,等支付。。


///     10个商品秒杀,一次只能进一个? 违背了业务


///    


/// 所以用上了Redis,一方面保证绝对不会超卖,


///                 另一方面没有效率影响,数据库是可以为成功的人并发的


///                 还有撤单的时候增加库存,可以继续秒杀,


///                 限制秒杀的库存是放在redis,不是数据库,不会造成数据的不一致性


///          


/// Redis能够拦截无效的请求,如果没有这一层,所有的请求压力都到数据库


///


/// 缓存击穿/穿透---缓存down掉,请求全部到数据库


/// 缓存预热功能---缓存重启,数据丢失,多了一个初始化缓存数据动作(写代码去把数据读出来放入缓存)




模拟超卖现象


复制代码




 public class OversellField


   {


       private static bool IsGoOn = true;//秒杀活动是否结束


       private static int Stock = 0;


       public static void Show()


       {


           Stock = 10;




           for (int i = 0; i < 5000; i++)


           {


               int k = i;


               Task.Run(() =>//每个线程就是一个用户请求


               {


                   if (IsGoOn)


                   {


                       long index = Stock;//-1并且返回 去数据库查一下当前的库存


                       Thread.Sleep(100);




                       if (index >= 1)


                       {


                           Stock = Stock - 1;//更新库存


                           Console.WriteLine($"{k.ToString("000")}秒杀成功,秒杀商品索引为{index}");


                           //可以分队列,去数据库操作


                       }


                       else


                       {


                           if (IsGoOn)


                           {


                               IsGoOn = false;


                           }


                           Console.WriteLine($"{k.ToString("000")}秒杀失败,秒杀商品索引为{index}");


                       }


                   }


                   else


                   {


                       Console.WriteLine($"{k.ToString("000")}秒杀停止......");


                   }


               });


           }


           Console.Read();


       }


   }




复制代码








利用redis解决超卖问题


复制代码




public class OversellTest


   {


       private static bool IsGoOn = true;//秒杀活动是否结束


       public static void Show()


       {


           using (RedisStringService service = new RedisStringService())


           {


               service.Set<int>("Stock", 10);//是库存


           }




           for (int i = 0; i < 5000; i++)


           {


               int k = i;


               Task.Run(() =>//每个线程就是一个用户请求


               {


                   using (RedisStringService service = new RedisStringService())


                   {


                       if (IsGoOn)


                       {


                           long index = service.Decr("Stock");//-1并且返回  


                           if (index >= 0)


                           {


                               Console.WriteLine($"{k.ToString("000")}秒杀成功,秒杀商品索引为{index}");


                               //service.Incr("Stock");//+1


                               //可以分队列,去数据库操作


                           }


                           else


                           {


                               if (IsGoOn)


                               {


                                   IsGoOn = false;


                               }


                               Console.WriteLine($"{k.ToString("000")}秒杀失败,秒杀商品索引为{index}");


                           }


                       }


                       else


                       {


                           Console.WriteLine($"{k.ToString("000")}秒杀停止......");


                       }


                   }


               });


           }


           Console.Read();


       }


   }




复制代码






Hashtable








redis 的Hash类型操作类


复制代码




   /// <summary>


   /// Hash:类似dictionary,通过索引快速定位到指定元素的,耗时均等,跟string的区别在于不用反序列化,直接修改某个字段


   /// string的话要么是 001:序列化整个实体


   ///           要么是 001_name:  001_pwd: 多个key-value


   /// Hash的话,一个hashid-{key:value;key:value;key:value;}


   /// 可以一次性查找实体,也可以单个,还可以单个修改


   /// </summary>


   public class RedisHashService : RedisBase


   {


       #region 添加


       /// <summary>


       /// 向hashid集合中添加key/value


       /// </summary>      


       public bool SetEntryInHash(string hashid, string key, string value)


       {


           return base.iClient.SetEntryInHash(hashid, key, value);


       }


       /// <summary>


       /// 如果hashid集合中存在key/value则不添加返回false,


       /// 如果不存在在添加key/value,返回true


       /// </summary>


       public bool SetEntryInHashIfNotExists(string hashid, string key, string value)


       {


           return base.iClient.SetEntryInHashIfNotExists(hashid, key, value);


       }


       /// <summary>


       /// 存储对象T t到hash集合中


       /// 需要包含Id,然后用Id获取


       /// </summary>


       public void StoreAsHash<T>(T t)


       {


           base.iClient.StoreAsHash<T>(t);


       }


       #endregion




       #region 获取


       /// <summary>


       /// 获取对象T中ID为id的数据。


       /// </summary>


       public T GetFromHash<T>(object id)


       {


           return base.iClient.GetFromHash<T>(id);


       }


       /// <summary>


       /// 获取所有hashid数据集的key/value数据集合


       /// </summary>


       public Dictionary<string, string> GetAllEntriesFromHash(string hashid)


       {


           return base.iClient.GetAllEntriesFromHash(hashid);


       }


       /// <summary>


       /// 获取hashid数据集中的数据总数


       /// </summary>


       public long GetHashCount(string hashid)


       {


           return base.iClient.GetHashCount(hashid);


       }


       /// <summary>


       /// 获取hashid数据集中所有key的集合


       /// </summary>


       public List<string> GetHashKeys(string hashid)


       {


           return base.iClient.GetHashKeys(hashid);


       }


       /// <summary>


       /// 获取hashid数据集中的所有value集合


       /// </summary>


       public List<string> GetHashValues(string hashid)


       {


           return base.iClient.GetHashValues(hashid);


       }


       /// <summary>


       /// 获取hashid数据集中,key的value数据


       /// </summary>


       public string GetValueFromHash(string hashid, string key)


       {


           return base.iClient.GetValueFromHash(hashid, key);


       }


       /// <summary>


       /// 获取hashid数据集中,多个keys的value集合


       /// </summary>


       public List<string> GetValuesFromHash(string hashid, string[] keys)


       {


           return base.iClient.GetValuesFromHash(hashid, keys);


       }


       #endregion




       #region 删除


       /// <summary>


       /// 删除hashid数据集中的key数据


       /// </summary>


       public bool RemoveEntryFromHash(string hashid, string key)


       {


           return base.iClient.RemoveEntryFromHash(hashid, key);


       }


       #endregion




       #region 其它


       /// <summary>


       /// 判断hashid数据集中是否存在key的数据


       /// </summary>


       public bool HashContainsEntry(string hashid, string key)


       {


           return base.iClient.HashContainsEntry(hashid, key);


       }


       /// <summary>


       /// 给hashid数据集key的value加countby,返回相加后的数据


       /// </summary>


       public double IncrementValueInHash(string hashid, string key, double countBy)


       {


           return base.iClient.IncrementValueInHash(hashid, key, countBy);


       }


       #endregion


   }




复制代码




使用


复制代码




Console.WriteLine("*****************************************");


           {


               using (RedisHashService service = new RedisHashService())


               {


                   service.SetEntryInHash("student", "id", "123456");


                   service.SetEntryInHash("student", "name", "张xx");


                   service.SetEntryInHash("student", "remark", "高级班的学员");




                   var keys = service.GetHashKeys("student");


                   var values = service.GetHashValues("student");


                   var keyValues = service.GetAllEntriesFromHash("student");


                   Console.WriteLine(service.GetValueFromHash("student", "id"));




                   service.SetEntryInHashIfNotExists("student", "name", "太子爷");


                   service.SetEntryInHashIfNotExists("student", "description", "高级班的学员2");




                   Console.WriteLine(service.GetValueFromHash("student", "name"));


                   Console.WriteLine(service.GetValueFromHash("student", "description"));


                   service.RemoveEntryFromHash("student", "description");


                   Console.WriteLine(service.GetValueFromHash("student", "description"));


               }


           }




复制代码






Set




redis 的Set类型操作类


复制代码




/// <summary>


   /// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据


   /// 1.共同好友、二度好友


   /// 2.利用唯一性,可以统计访问网站的所有独立 IP


   /// </summary>


   public class RedisSetService : RedisBase


   {


       #region 添加


       /// <summary>


       /// key集合中添加value值


       /// </summary>


       public void Add(string key, string value)


       {


           base.iClient.AddItemToSet(key, value);


       }


       /// <summary>


       /// key集合中添加list集合


       /// </summary>


       public void Add(string key, List<string> list)


       {


           base.iClient.AddRangeToSet(key, list);




       }


       #endregion




       #region 获取


       /// <summary>


       /// 随机获取key集合中的一个值


       /// </summary>


       public string GetRandomItemFromSet(string key)


       {


           return base.iClient.GetRandomItemFromSet(key);


       }


       /// <summary>


       /// 获取key集合值的数量


       /// </summary>


       public long GetCount(string key)


       {


           return base.iClient.GetSetCount(key);


       }


       /// <summary>


       /// 获取所有key集合的值


       /// </summary>


       public HashSet<string> GetAllItemsFromSet(string key)


       {


           return base.iClient.GetAllItemsFromSet(key);


       }


       #endregion




       #region 删除


       /// <summary>


       /// 随机删除key集合中的一个值


       /// </summary>


       public string RandomRemoveItemFromSet(string key)


       {


           return base.iClient.PopItemFromSet(key);


       }


       /// <summary>


       /// 删除key集合中的value


       /// </summary>


       public void RemoveItemFromSet(string key, string value)


       {


           base.iClient.RemoveItemFromSet(key, value);


       }


       #endregion




       #region 其它


       /// <summary>


       /// 从fromkey集合中移除值为value的值,并把value添加到tokey集合中


       /// </summary>


       public void MoveBetweenSets(string fromkey, string tokey, string value)


       {


           base.iClient.MoveBetweenSets(fromkey, tokey, value);


       }


       /// <summary>


       /// 返回keys多个集合中的并集,返还hashset


       /// </summary>


       public HashSet<string> GetUnionFromSets(params string[] keys)


       {


           return base.iClient.GetUnionFromSets(keys);


       }


       /// <summary>


       /// 返回keys多个集合中的交集,返还hashset


       /// </summary>


       public HashSet<string> GetIntersectFromSets(params string[] keys)


       {


           return base.iClient.GetIntersectFromSets(keys);


       }


       /// <summary>


       /// 返回keys多个集合中的差集,返还hashset


       /// </summary>


       /// <param name="fromKey">原集合</param>


       /// <param name="keys">其他集合</param>


       /// <returns>出现在原集合,但不包含在其他集合</returns>


       public HashSet<string> GetDifferencesFromSet(string fromKey, params string[] keys)


       {


           return base.iClient.GetDifferencesFromSet(fromKey,keys);


       }


       /// <summary>


       /// keys多个集合中的并集,放入newkey集合中


       /// </summary>


       public void StoreUnionFromSets(string newkey, string[] keys)


       {


           base.iClient.StoreUnionFromSets(newkey, keys);


       }


       /// <summary>


       /// 把fromkey集合中的数据与keys集合中的数据对比,fromkey集合中不存在keys集合中,则把这些不存在的数据放入newkey集合中


       /// </summary>


       public void StoreDifferencesFromSet(string newkey, string fromkey, string[] keys)


       {


           base.iClient.StoreDifferencesFromSet(newkey, fromkey, keys);


       }


       #endregion


   }




复制代码




使用


复制代码




 Console.WriteLine("*****************************************");


           {


               using (RedisSetService service = new RedisSetService())


               {


                   service.FlushAll();//清理全部数据




                   service.Add("advanced", "111");


                   service.Add("advanced", "112");


                   service.Add("advanced", "114");


                   service.Add("advanced", "114");


                   service.Add("advanced", "115");


                   service.Add("advanced", "115");


                   service.Add("advanced", "113");




                   var result = service.GetAllItemsFromSet("advanced");




                   var random = service.GetRandomItemFromSet("advanced");//随机获取


                   service.GetCount("advanced");//独立的ip数


                   service.RemoveItemFromSet("advanced", "114");




                   {


                       service.Add("begin", "111");


                       service.Add("begin", "112");


                       service.Add("begin", "115");




                       service.Add("end", "111");


                       service.Add("end", "114");


                       service.Add("end", "113");




                       var result1 = service.GetIntersectFromSets("begin", "end");


                       var result2 = service.GetDifferencesFromSet("begin", "end");


                       var result3 = service.GetUnionFromSets("begin", "end");


                       //共同好友   共同关注


                   }


               }


           }




复制代码




去重验证




删除Item验证




集合的交差并






ZSet




redis 的zset类型操作类


复制代码




   /// <summary>


   /// Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列


   /// 1.带有权重的元素,比如一个游戏的用户得分排行榜


   /// 2.比较复杂的数据结构,一般用到的场景不算太多


   /// </summary>


   public class RedisZSetService : RedisBase


   {


       #region 添加


       /// <summary>


       /// 添加key/value,默认分数是从1.多*10的9次方以此递增的,自带自增效果


       /// </summary>


       public bool Add(string key, string value)


       {


           return base.iClient.AddItemToSortedSet(key, value);


       }


       /// <summary>


       /// 添加key/value,并设置value的分数


       /// </summary>


       public bool AddItemToSortedSet(string key, string value, double score)


       {


           return base.iClient.AddItemToSortedSet(key, value, score);


       }


       /// <summary>


       /// 为key添加values集合,values集合中每个value的分数设置为score


       /// </summary>


       public bool AddRangeToSortedSet(string key, List<string> values, double score)


       {


           return base.iClient.AddRangeToSortedSet(key, values, score);


       }


       /// <summary>


       /// 为key添加values集合,values集合中每个value的分数设置为score


       /// </summary>


       public bool AddRangeToSortedSet(string key, List<string> values, long score)


       {


           return base.iClient.AddRangeToSortedSet(key, values, score);


       }


       #endregion




       #region 获取


       /// <summary>


       /// 获取key的所有集合


       /// </summary>


       public List<string> GetAll(string key)


       {


           return base.iClient.GetAllItemsFromSortedSet(key);


       }


       /// <summary>


       /// 获取key的所有集合,倒叙输出


       /// </summary>


       public List<string> GetAllDesc(string key)


       {


           return base.iClient.GetAllItemsFromSortedSetDesc(key);


       }


       /// <summary>


       /// 获取集合,带分数


       /// </summary>


       public IDictionary<string, double> GetAllWithScoresFromSortedSet(string key)


       {


           return base.iClient.GetAllWithScoresFromSortedSet(key);


       }


       /// <summary>


       /// 获取key为value的下标值


       /// </summary>


       public long GetItemIndexInSortedSet(string key, string value)


       {


           return base.iClient.GetItemIndexInSortedSet(key, value);


       }


       /// <summary>


       /// 倒叙排列获取key为value的下标值


       /// </summary>


       public long GetItemIndexInSortedSetDesc(string key, string value)


       {


           return base.iClient.GetItemIndexInSortedSetDesc(key, value);


       }


       /// <summary>


       /// 获取key为value的分数


       /// </summary>


       public double GetItemScoreInSortedSet(string key, string value)


       {


           return base.iClient.GetItemScoreInSortedSet(key, value);


       }


       /// <summary>


       /// 获取key所有集合的数据总数


       /// </summary>


       public long GetSortedSetCount(string key)


       {


           return base.iClient.GetSortedSetCount(key);


       }


       /// <summary>


       /// key集合数据从分数为fromscore到分数为toscore的数据总数


       /// </summary>


       public long GetSortedSetCount(string key, double fromScore, double toScore)


       {


           return base.iClient.GetSortedSetCount(key, fromScore, toScore);


       }


       /// <summary>


       /// 获取key集合从高分到低分排序数据,分数从fromscore到分数为toscore的数据


       /// </summary>


       public List<string> GetRangeFromSortedSetByHighestScore(string key, double fromscore, double toscore)


       {


           return base.iClient.GetRangeFromSortedSetByHighestScore(key, fromscore, toscore);


       }


       /// <summary>


       /// 获取key集合从低分到高分排序数据,分数从fromscore到分数为toscore的数据


       /// </summary>


       public List<string> GetRangeFromSortedSetByLowestScore(string key, double fromscore, double toscore)


       {


           return base.iClient.GetRangeFromSortedSetByLowestScore(key, fromscore, toscore);


       }


       /// <summary>


       /// 获取key集合从高分到低分排序数据,分数从fromscore到分数为toscore的数据,带分数


       /// </summary>


       public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, double fromscore, double toscore)


       {


           return base.iClient.GetRangeWithScoresFromSortedSetByHighestScore(key, fromscore, toscore);


       }


       /// <summary>


       ///  获取key集合从低分到高分排序数据,分数从fromscore到分数为toscore的数据,带分数


       /// </summary>


       public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, double fromscore, double toscore)


       {


           return base.iClient.GetRangeWithScoresFromSortedSetByLowestScore(key, fromscore, toscore);


       }


       /// <summary>


       ///  获取key集合数据,下标从fromRank到分数为toRank的数据


       /// </summary>


       public List<string> GetRangeFromSortedSet(string key, int fromRank, int toRank)


       {


           return base.iClient.GetRangeFromSortedSet(key, fromRank, toRank);


       }


       /// <summary>


       /// 获取key集合倒叙排列数据,下标从fromRank到分数为toRank的数据


       /// </summary>


       public List<string> GetRangeFromSortedSetDesc(string key, int fromRank, int toRank)


       {


           return base.iClient.GetRangeFromSortedSetDesc(key, fromRank, toRank);


       }


       /// <summary>


       /// 获取key集合数据,下标从fromRank到分数为toRank的数据,带分数


       /// </summary>


       public IDictionary<string, double> GetRangeWithScoresFromSortedSet(string key, int fromRank, int toRank)


       {


           return base.iClient.GetRangeWithScoresFromSortedSet(key, fromRank, toRank);


       }


       /// <summary>


       ///  获取key集合倒叙排列数据,下标从fromRank到分数为toRank的数据,带分数


       /// </summary>


       public IDictionary<string, double> GetRangeWithScoresFromSortedSetDesc(string key, int fromRank, int toRank)


       {


           return base.iClient.GetRangeWithScoresFromSortedSetDesc(key, fromRank, toRank);


       }


       #endregion




       #region 删除


       /// <summary>


       /// 删除key为value的数据


       /// </summary>


       public bool RemoveItemFromSortedSet(string key, string value)


       {


           return base.iClient.RemoveItemFromSortedSet(key, value);


       }


       /// <summary>


       /// 删除下标从minRank到maxRank的key集合数据


       /// </summary>


       public long RemoveRangeFromSortedSet(string key, int minRank, int maxRank)


       {


           return base.iClient.RemoveRangeFromSortedSet(key, minRank, maxRank);


       }


       /// <summary>


       /// 删除分数从fromscore到toscore的key集合数据


       /// </summary>


       public long RemoveRangeFromSortedSetByScore(string key, double fromscore, double toscore)


       {


           return base.iClient.RemoveRangeFromSortedSetByScore(key, fromscore, toscore);


       }


       /// <summary>


       /// 删除key集合中分数最大的数据


       /// </summary>


       public string PopItemWithHighestScoreFromSortedSet(string key)


       {


           return base.iClient.PopItemWithHighestScoreFromSortedSet(key);


       }


       /// <summary>


       /// 删除key集合中分数最小的数据


       /// </summary>


       public string PopItemWithLowestScoreFromSortedSet(string key)


       {


           return base.iClient.PopItemWithLowestScoreFromSortedSet(key);


       }


       #endregion




       #region 其它


       /// <summary>


       /// 判断key集合中是否存在value数据


       /// </summary>


       public bool SortedSetContainsItem(string key, string value)


       {


           return base.iClient.SortedSetContainsItem(key, value);


       }


       /// <summary>


       /// 为key集合值为value的数据,分数加scoreby,返回相加后的分数


       /// </summary>


       public double IncrementItemInSortedSet(string key, string value, double scoreBy)


       {


           return base.iClient.IncrementItemInSortedSet(key, value, scoreBy);


       }


       /// <summary>


       /// 获取keys多个集合的交集,并把交集添加的newkey集合中,返回交集数据的总数


       /// </summary>


       public long StoreIntersectFromSortedSets(string newkey, string[] keys)


       {


           return base.iClient.StoreIntersectFromSortedSets(newkey, keys);


       }


       /// <summary>


       /// 获取keys多个集合的并集,并把并集数据添加到newkey集合中,返回并集数据的总数


       /// </summary>


       public long StoreUnionFromSortedSets(string newkey, string[] keys)


       {


           return base.iClient.StoreUnionFromSortedSets(newkey, keys);


       }


       #endregion


   }




复制代码




使用除了排序,其他与Set一样


复制代码




Console.WriteLine("*****************************************");


           {


               using (RedisZSetService service = new RedisZSetService())


               {


                   service.FlushAll();//清理全部数据




                   service.Add("advanced", "1");


                   service.Add("advanced", "2");


                   service.Add("advanced", "5");


                   service.Add("advanced", "4");


                   service.Add("advanced", "7");


                   service.Add("advanced", "5");


                   service.Add("advanced", "9");




                   var result1 = service.GetAll("advanced");


                   var result2 = service.GetAllDesc("advanced");




                   service.AddItemToSortedSet("Sort", "BY", 123234);


                   service.AddItemToSortedSet("Sort", "走自己的路", 123);


                   service.AddItemToSortedSet("Sort", "redboy", 45);


                   service.AddItemToSortedSet("Sort", "大蛤蟆", 7567);


                   service.AddItemToSortedSet("Sort", "路人甲", 9879);


                   service.AddRangeToSortedSet("Sort", new List<string>() { "123", "花生", "加菲猫" }, 3232);


                   var result3 = service.GetAllWithScoresFromSortedSet("Sort");




                   //交叉并


               }


           }




复制代码




排序值、及排序结果




















场景(实时排行)


复制代码




/// <summary>


   /// 实时排行榜:刷个礼物


   /// 维度很多,平台/房间/主播/日/周/月/年


   /// A对B 刷个礼物,影响很多


   /// 刷礼物只记录流水,不影响排行,凌晨24点跑任务更新


   ///


   /// 实时排行榜


   /// Redis-IncrementItemInSortedSet


   /// 刷礼物时增加redis分数


   /// 就可以实时获取最新的排行


   /// (多个维度就是多个zSet,刷礼物的时候保存数据库并更新Redis)


   /// </summary>


   public class RankManager


   {


       private static List<string> UserList = new List<string>()


       {


           "Tenk","花生","Ray","阿莫西林","石昊","ywa"


       };


       public static void Show()


       {


           using (RedisZSetService service = new RedisZSetService())


           {


               service.FlushAll();//清理全部数据




               Task.Run(() =>


               {


                   while (true)


                   {


                       foreach (var user in UserList)


                       {


                           Thread.Sleep(10);


                           service.IncrementItemInSortedSet("陈一发儿", user, new Random().Next(1, 100));//表示在原来刷礼物的基础上增加礼物


                       }


                       Thread.Sleep(20 * 1000);


                   }


               });




               Task.Run(() =>


               {


                   while (true)


                   {


                       Thread.Sleep(12 * 1000);


                       Console.WriteLine("**********当前排行************");


                       int i = 1;




                       foreach (var item in service.GetAllWithScoresFromSortedSet("陈一发儿"))


                       {


                           Console.WriteLine($"第{i++}名 {item.Key} 分数{item.Value}");


                       }


                       //foreach (var item in service.GetAllDesc("陈一发儿"))


                       //{


                       //    Console.WriteLine($"第{i++}名 {item}");


                       //}


                   }


               });




               Console.Read();




           }




       }


   }




复制代码




List




redis 的List类型操作类


复制代码




   /// <summary>


   ///  Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,


   ///  Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。  


   /// </summary>


   public class RedisListService : RedisBase


   {


       #region 赋值


       /// <summary>


       /// 从左侧向list中添加值


       /// </summary>


       public void LPush(string key, string value)


       {


           base.iClient.PushItemToList(key, value);


       }


       /// <summary>


       /// 从左侧向list中添加值,并设置过期时间


       /// </summary>


       public void LPush(string key, string value, DateTime dt)


       {




           base.iClient.PushItemToList(key, value);


           base.iClient.ExpireEntryAt(key, dt);


       }


       /// <summary>


       /// 从左侧向list中添加值,设置过期时间


       /// </summary>


       public void LPush(string key, string value, TimeSpan sp)


       {


           base.iClient.PushItemToList(key, value);


           base.iClient.ExpireEntryIn(key, sp);


       }


       /// <summary>


       /// 从右侧向list中添加值


       /// </summary>


       public void RPush(string key, string value)


       {


           base.iClient.PrependItemToList(key, value);


       }


       /// <summary>


       /// 从右侧向list中添加值,并设置过期时间


       /// </summary>    


       public void RPush(string key, string value, DateTime dt)


       {


           base.iClient.PrependItemToList(key, value);


           base.iClient.ExpireEntryAt(key, dt);


       }


       /// <summary>


       /// 从右侧向list中添加值,并设置过期时间


       /// </summary>        


       public void RPush(string key, string value, TimeSpan sp)


       {


           base.iClient.PrependItemToList(key, value);


           base.iClient.ExpireEntryIn(key, sp);


       }


       /// <summary>


       /// 添加key/value


       /// </summary>    


       public void Add(string key, string value)


       {


           base.iClient.AddItemToList(key, value);


       }


       /// <summary>


       /// 添加key/value ,并设置过期时间


       /// </summary>  


       public void Add(string key, string value, DateTime dt)


       {


           base.iClient.AddItemToList(key, value);


           base.iClient.ExpireEntryAt(key, dt);


       }


       /// <summary>


       /// 添加key/value。并添加过期时间


       /// </summary>  


       public void Add(string key, string value, TimeSpan sp)


       {


           base.iClient.AddItemToList(key, value);


           base.iClient.ExpireEntryIn(key, sp);


       }


       /// <summary>


       /// 为key添加多个值


       /// </summary>  


       public void Add(string key, List<string> values)


       {


           base.iClient.AddRangeToList(key, values);


       }


       /// <summary>


       /// 为key添加多个值,并设置过期时间


       /// </summary>  


       public void Add(string key, List<string> values, DateTime dt)


       {


           base.iClient.AddRangeToList(key, values);


           base.iClient.ExpireEntryAt(key, dt);


       }


       /// <summary>


       /// 为key添加多个值,并设置过期时间


       /// </summary>  


       public void Add(string key, List<string> values, TimeSpan sp)


       {


           base.iClient.AddRangeToList(key, values);


           base.iClient.ExpireEntryIn(key, sp);


       }


       #endregion




       #region 获取值


       /// <summary>


       /// 获取list中key包含的数据数量


       /// </summary>  


       public long Count(string key)


       {


           return base.iClient.GetListCount(key);


       }


       /// <summary>


       /// 获取key包含的所有数据集合


       /// </summary>  


       public List<string> Get(string key)


       {


           return base.iClient.GetAllItemsFromList(key);


       }


       /// <summary>


       /// 获取key中下标为star到end的值集合


       /// </summary>  


       public List<string> Get(string key, int star, int end)


       {


           return base.iClient.GetRangeFromList(key, star, end);


       }


       #endregion




       #region 阻塞命令


       /// <summary>


       ///  阻塞命令:从list为key的尾部移除一个值,并返回移除的值,阻塞时间为sp


       /// </summary>  


       public string BlockingPopItemFromList(string key, TimeSpan? sp)


       {


           return base.iClient.BlockingPopItemFromList(key, sp);


       }


       /// <summary>


       ///  阻塞命令:从多个list中尾部移除一个值,并返回移除的值&key,阻塞时间为sp


       /// </summary>  


       public ItemRef BlockingPopItemFromLists(string[] keys, TimeSpan? sp)


       {


           return base.iClient.BlockingPopItemFromLists(keys, sp);


       }






       /// <summary>


       ///  阻塞命令:从list中keys的尾部移除一个值,并返回移除的值,阻塞时间为sp


       /// </summary>  


       public string BlockingDequeueItemFromList(string key, TimeSpan? sp)


       {


           return base.iClient.BlockingDequeueItemFromList(key, sp);


       }




       /// <summary>


       /// 阻塞命令:从多个list中尾部移除一个值,并返回移除的值&key,阻塞时间为sp


       /// </summary>  


       public ItemRef BlockingDequeueItemFromLists(string[] keys, TimeSpan? sp)


       {


           return base.iClient.BlockingDequeueItemFromLists(keys, sp);


       }




       /// <summary>


       /// 阻塞命令:从list中一个fromkey的尾部移除一个值,添加到另外一个tokey的头部,并返回移除的值,阻塞时间为sp


       /// </summary>  


       public string BlockingPopAndPushItemBetweenLists(string fromkey, string tokey, TimeSpan? sp)


       {


           return base.iClient.BlockingPopAndPushItemBetweenLists(fromkey, tokey, sp);


       }


       #endregion




       #region 删除


       /// <summary>


       /// 从尾部移除数据,返回移除的数据


       /// </summary>  


       public string PopItemFromList(string key)


       {


           var sa = base.iClient.CreateSubscription();


           return base.iClient.PopItemFromList(key);


       }


       /// <summary>


       /// 从尾部移除数据,返回移除的数据


       /// </summary>  


       public string DequeueItemFromList(string key)


       {


           return base.iClient.DequeueItemFromList(key);


       }




       /// <summary>


       /// 移除list中,key/value,与参数相同的值,并返回移除的数量


       /// </summary>  


       public long RemoveItemFromList(string key, string value)


       {


           return base.iClient.RemoveItemFromList(key, value);


       }


       /// <summary>


       /// 从list的尾部移除一个数据,返回移除的数据


       /// </summary>  


       public string RemoveEndFromList(string key)


       {


           return base.iClient.RemoveEndFromList(key);


       }


       /// <summary>


       /// 从list的头部移除一个数据,返回移除的值


       /// </summary>  


       public string RemoveStartFromList(string key)


       {


           return base.iClient.RemoveStartFromList(key);


       }


       #endregion




       #region 其它


       /// <summary>


       /// 从一个list的尾部移除一个数据,添加到另外一个list的头部,并返回移动的值


       /// </summary>  


       public string PopAndPushItemBetweenLists(string fromKey, string toKey)


       {


           return base.iClient.PopAndPushItemBetweenLists(fromKey, toKey);


       }






       public void TrimList(string key, int start, int end)


       {


           base.iClient.TrimList(key, start, end);


       }


       #endregion




       #region 发布订阅


       public void Publish(string channel, string message)


       {


           base.iClient.PublishMessage(channel, message);


       }




       public void Subscribe(string channel, Action<string, string, IRedisSubscription> actionOnMessage)


       {


           var subscription = base.iClient.CreateSubscription();


           subscription.OnSubscribe = c =>


           {


               Console.WriteLine($"订阅频道{c}");


               Console.WriteLine();


           };


           //取消订阅


           subscription.OnUnSubscribe = c =>


           {


               Console.WriteLine($"取消订阅 {c}");


               Console.WriteLine();


           };


           subscription.OnMessage += (c, s) =>


           {


               actionOnMessage(c, s, subscription);


           };


           Console.WriteLine($"开始启动监听 {channel}");


           subscription.SubscribeToChannels(channel); //blocking


       }




       public void UnSubscribeFromChannels(string channel)


       {


           var subscription = base.iClient.CreateSubscription();


           subscription.UnSubscribeFromChannels(channel);


       }


       #endregion


   }




复制代码




使用


复制代码




             Console.WriteLine("*****************************************");


           {


               using (RedisListService service = new RedisListService())


               {


                   service.FlushAll();




                   service.Add("article", "eleven1234");


                   service.Add("article", "kevin");


                   service.Add("article", "大叔");


                   service.Add("article", "C卡");


                   service.Add("article", "触不到的线");


                   service.Add("article", "程序错误");




                   var result1 = service.Get("article");


                   var result2 = service.Get("article", 0, 3);


             


               }




复制代码




后进先出(栈的效果)


复制代码




                   service.FlushAll();




                   service.Add("article", "eleven1234");


                   service.Add("article", "kevin");


                   service.Add("article", "大叔");


                   service.Add("article", "C卡");


                   service.Add("article", "触不到的线");


                   service.Add("article", "程序错误");




                   for (int i = 0; i < 5; i++)


                   {


                       Console.WriteLine(service.PopItemFromList("article"));


                       var result1 = service.Get("article");


                   }




复制代码




i=0 时




i=1时




i=2时




先进先出(队列的效果)


复制代码




// 队列:生产者消费者模型


                   service.FlushAll();


                   service.RPush("article", "eleven1234");


                   service.RPush("article", "kevin");


                   service.RPush("article", "大叔");


                   service.RPush("article", "C卡");


                   service.RPush("article", "触不到的线");


                   service.RPush("article", "程序错误");




                   for (int i = 0; i < 5; i++)


                   {


                       Console.WriteLine(service.PopItemFromList("article"));


                       var result1 = service.Get("article");


                   }


                   //分布式缓存,多服务器都可以访问到,多个生产者,多个消费者,任何产品只被消费一次




复制代码




i=0时








i=1时








i=2时




生产者


复制代码




using (RedisListService service = new RedisListService())


               {


                   List<string> stringList = new List<string>();


                   for (int i = 0; i < 10; i++)


                   {


                       stringList.Add(string.Format($"放入任务{i}"));


                   }




                   service.Add("test", "这是一个学生Add1");


                   service.Add("test", "这是一个学生Add2");


                   service.Add("test", "这是一个学生Add3");




                   service.LPush("test", "这是一个学生LPush1");


                   service.LPush("test", "这是一个学生LPush2");


                   service.LPush("test", "这是一个学生LPush3");


                   service.LPush("test", "这是一个学生LPush4");


                   service.LPush("test", "这是一个学生LPush5");


                   service.LPush("test", "这是一个学生LPush6");




                   service.RPush("test", "这是一个学生RPush1");


                   service.RPush("test", "这是一个学生RPush2");


                   service.RPush("test", "这是一个学生RPush3");


                   service.RPush("test", "这是一个学生RPush4");


                   service.RPush("test", "这是一个学生RPush5");


                   service.RPush("test", "这是一个学生RPush6");


                   service.Add("task", stringList);




                   Console.WriteLine(service.Count("test"));


                   Console.WriteLine(service.Count("task"));


                   var list = service.Get("test");


                   list = service.Get("task", 2, 4);




                   Action act = new Action(() =>


                   {


                       while (true)


                       {


                           Console.WriteLine("************请输入数据**************");


                           string testTask = Console.ReadLine();


                           service.LPush("test", testTask);


                       }


                   });


                   act.EndInvoke(act.BeginInvoke(null, null));


               }




复制代码












消费者


复制代码




   public class ServiceStackProcessor


   {


       public static void Show()


       {


           string path = AppDomain.CurrentDomain.BaseDirectory;


           string tag = path.Split('/', '\\').Last(s => !string.IsNullOrEmpty(s));


           Console.WriteLine($"这里是 {tag} 启动了。。");


           using (RedisListService service = new RedisListService())


           {


               Action act = new Action(() =>


               {


                   while (true)


                   {


                       var result = service.BlockingPopItemFromLists(new string[] { "test", "task" }, TimeSpan.FromHours(3));


                       Thread.Sleep(100);


                       Console.WriteLine($"这里是 {tag} 队列获取的消息 {result.Id} {result.Item}");


                   }


               });


               act.EndInvoke(act.BeginInvoke(null, null));


           }


       }




   }




复制代码




可以 一个生产者对应多个消费者,也可以一个消费者对应多个生产者,多对多也可以




下面是 一个生产者对应多个消费者的效果图








发布订阅




发布订阅:观察者,一个数据源,多个接受者,只要订阅了就可以收到的,能被多个数据源共享


复制代码




     #region 发布订阅:观察者,一个数据源,多个接受者,只要订阅了就可以收到的,能被多个数据源共享


               Task.Run(() =>


               {


                   using (RedisListService service = new RedisListService())


                   {


                       //订阅频道


                       service.Subscribe("Eleven", (c, message, iRedisSubscription) =>


                       {


                           Console.WriteLine($"注册{1}{c}:{message},Dosomething else");


                           if (message.Equals("exit"))


                               iRedisSubscription.UnSubscribeFromChannels("Eleven");//取消订阅频道


                       });//blocking


                   }


               });


               Task.Run(() =>


               {


                   using (RedisListService service = new RedisListService())


                   {


                       //订阅频道


                       service.Subscribe("Eleven", (c, message, iRedisSubscription) =>


                       {


                           Console.WriteLine($"注册{2}{c}:{message},Dosomething else");


                           if (message.Equals("exit"))


                               iRedisSubscription.UnSubscribeFromChannels("Eleven");//取消订阅频道


                       });//blocking


                   }


               });


               Task.Run(() =>


               {


                   using (RedisListService service = new RedisListService())


                   {


                       //订阅频道


                       service.Subscribe("Twelve", (c, message, iRedisSubscription) =>


                       {


                           Console.WriteLine($"注册{3}{c}:{message},Dosomething else");


                           if (message.Equals("exit"))


                               iRedisSubscription.UnSubscribeFromChannels("Twelve");//取消订阅频道


                       });//blocking


                   }


               });


               using (RedisListService service = new RedisListService())


               {


                   Thread.Sleep(1000);


                   //频道发布消息


                   service.Publish("Eleven", "Eleven123");


                   service.Publish("Eleven", "Eleven234");


                   service.Publish("Eleven", "Eleven345");


                   service.Publish("Eleven", "Eleven456");


                   //频道发布消息


                   service.Publish("Twelve", "Twelve123");


                   service.Publish("Twelve", "Twelve234");


                   service.Publish("Twelve", "Twelve345");


                   service.Publish("Twelve", "Twelve456");


                   Console.WriteLine("**********************************************");


                   //频道发布 封号退出消息


                   service.Publish("Eleven", "exit");




                   service.Publish("Eleven", "123Eleven");


                   service.Publish("Eleven", "234Eleven");


                   service.Publish("Eleven", "345Eleven");


                   service.Publish("Eleven", "456Eleven");


                   //频道发布 封号退出消息


                   service.Publish("Twelve", "exit");


                   service.Publish("Twelve", "123Twelve");


                   service.Publish("Twelve", "234Twelve");


                   service.Publish("Twelve", "345Twelve");


                   service.Publish("Twelve", "456Twelve");


               }


               #endregion




复制代码
























-----------------------------------------------------------------------------------------------------------------




StackExchange.Redis






下面额代码类均是通过 StackExchange.Redis 来对Redis进行各种操作




Redis操作方法基础类


复制代码




   /// <summary>


   /// Redis操作方法基础类


   /// </summary>


   public abstract class RedisBase : IDisposable


   {




       #region 属性字段


       /// <summary>


       /// 网站Redis 系统自定义Key前缀


       /// </summary>


       protected string CustomKey = RedisManager.RedisSysCustomKey;


       /// <summary>


       /// 网站Redis 链接字符串


       /// </summary>


       protected readonly ConnectionMultiplexer _conn;


       /// <summary>


       /// Redis操作对象


       /// </summary>


       protected readonly IDatabase redis = null;


       #endregion




       #region 构造函数


       /// <summary>


       /// 初始化Redis操作方法基础类


       /// </summary>


       /// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>


       protected RedisBase(int? dbNum = null)


       {


           _conn = RedisManager.Instance;


           if (_conn != null)


           {


               redis = _conn.GetDatabase(dbNum ?? RedisManager.RedisDataBaseIndex);


           }


           else


           {


               throw new ArgumentNullException("Redis连接初始化失败");


           }


       }




       private bool _disposed = false;


       protected virtual void Dispose(bool disposing)


       {


           if (!this._disposed)


           {


               if (disposing)


               {


                   _conn.Dispose();


               }


           }


           this._disposed = true;


       }


       public void Dispose()


       {


           Dispose(true);


           GC.SuppressFinalize(this);


       }


       #endregion 构造函数




       #region 外部调用静态方法


       /// <summary>


       /// 获取Redis的String数据类型操作辅助方法类


       /// </summary>


       /// <returns></returns>


       public static RedisStringService StringService => new RedisStringService();


       /// <summary>


       /// 获取Redis的Hash数据类型操作辅助方法类


       /// </summary>


       /// <returns></returns>


       public static RedisHashService HashService => new RedisHashService();


       /// <summary>


       /// 获取Redis的List数据类型操作辅助方法类


       /// </summary>


       /// <returns></returns>


       public static RedisListService ListService => new RedisListService();


       /// <summary>


       /// 获取Redis的Set无序集合数据类型操作辅助方法类


       /// </summary>


       /// <returns></returns>


       public static RedisSetService SetService => new RedisSetService();


       /// <summary>


       /// 获取Redis的SortedSet(ZSet)有序集合数据类型操作辅助方法类


       /// </summary>


       /// <returns></returns>


       public static RedisSortedSetService SortedSetService => new RedisSortedSetService();




       #endregion




       #region 公共操作方法




       #region 不建议公开这些方法,如果项目中用不到,建议注释或者删除


       /// <summary>


       /// 获取Redis事务对象


       /// </summary>


       /// <returns></returns>


       public ITransaction CreateTransaction() => redis.CreateTransaction();




       /// <summary>


       /// 获取Redis服务和常用操作对象


       /// </summary>


       /// <returns></returns>


       public IDatabase GetDatabase() => redis;




       /// <summary>


       /// 获取Redis服务


       /// </summary>


       /// <param name="hostAndPort"></param>


       /// <returns></returns>


       public IServer GetServer(string hostAndPort) => _conn.GetServer(hostAndPort);




       /// <summary>


       /// 执行Redis事务


       /// </summary>


       /// <param name="act"></param>


       /// <returns></returns>


       public bool RedisTransaction(Action<ITransaction> act)


       {


           var tran = redis.CreateTransaction();


           act.Invoke(tran);


           bool committed = tran.Execute();


           return committed;


       }


       /// <summary>


       /// Redis锁


       /// </summary>


       /// <param name="act"></param>


       /// <param name="ts">锁住时间</param>


       public void RedisLockTake(Action act, TimeSpan ts)


       {


           RedisValue token = Environment.MachineName;


           string lockKey = "lock_LockTake";


           if (redis.LockTake(lockKey, token, ts))


           {


               try


               {


                   act();


               }


               finally


               {


                   redis.LockRelease(lockKey, token);


               }


           }


       }


       #endregion 其他




       #region 常用Key操作


       /// <summary>


       /// 设置前缀


       /// </summary>


       /// <param name="customKey"></param>


       public void SetSysCustomKey(string customKey) => CustomKey = customKey;




       /// <summary>


       /// 组合缓存Key名称


       /// </summary>


       /// <param name="oldKey"></param>


       /// <returns></returns>


       public string AddSysCustomKey(string oldKey) => $"{CustomKey}_{oldKey}";




       #region 同步方法




       /// <summary>


       /// 删除单个key


       /// </summary>


       /// <param name="key">要删除的key</param>


       /// <returns>是否删除成功</returns>


       public bool KeyDelete(string key)


       {


           key = AddSysCustomKey(key);


           return redis.KeyDelete(key);


       }




       /// <summary>


       /// 删除多个key


       /// </summary>


       /// <param name="keys">要删除的key集合</param>


       /// <returns>成功删除的个数</returns>


       public long KeyDelete(params string[] keys)


       {


           RedisKey[] newKeys = keys.Select(o => (RedisKey)AddSysCustomKey(o)).ToArray();


           return redis.KeyDelete(newKeys);


       }




       /// <summary>


       /// 清空当前DataBase中所有Key


       /// </summary>


       public void KeyFulsh()


       {


           //直接执行清除命令


           redis.Execute("FLUSHDB");


       }




       /// <summary>


       /// 判断key是否存在


       /// </summary>


       /// <param name="key">要判断的key</param>


       /// <returns></returns>


       public bool KeyExists(string key)


       {


           key = AddSysCustomKey(key);


           return redis.KeyExists(key);


       }




       /// <summary>


       /// 重新命名key


       /// </summary>


       /// <param name="key">就的redis key</param>


       /// <param name="newKey">新的redis key</param>


       /// <returns></returns>


       public bool KeyRename(string key, string newKey)


       {


           key = AddSysCustomKey(key);


           newKey = AddSysCustomKey(newKey);


           return redis.KeyRename(key, newKey);


       }




       /// <summary>


       /// 设置Key的过期时间


       /// </summary>


       /// <param name="key">redis key</param>


       /// <param name="expiry">过期时间</param>


       /// <returns></returns>


       public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?))


       {


           key = AddSysCustomKey(key);


           return redis.KeyExpire(key, expiry);


       }






       #endregion




       #region 异步方法




       /// <summary>


       /// 删除单个key


       /// </summary>


       /// <param name="key">要删除的key</param>


       /// <returns>是否删除成功</returns>


       public async Task<bool> KeyDeleteAsync(string key)


       {


           key = AddSysCustomKey(key);


           return await redis.KeyDeleteAsync(key);


       }




       /// <summary>


       /// 删除多个key


       /// </summary>


       /// <param name="keys">要删除的key集合</param>


       /// <returns>成功删除的个数</returns>


       public async Task<long> KeyDeleteAsync(params string[] keys)


       {


           RedisKey[] newKeys = keys.Select(o => (RedisKey)AddSysCustomKey(o)).ToArray();


           return await redis.KeyDeleteAsync(newKeys);


       }




       /// <summary>


       /// 清空当前DataBase中所有Key


       /// </summary>


       public async Task KeyFulshAsync()


       {


           //直接执行清除命令


           await redis.ExecuteAsync("FLUSHDB");


       }




       /// <summary>


       /// 判断key是否存在


       /// </summary>


       /// <param name="key">要判断的key</param>


       /// <returns></returns>


       public async Task<bool> KeyExistsAsync(string key)


       {


           key = AddSysCustomKey(key);


           return await redis.KeyExistsAsync(key);


       }




       /// <summary>


       /// 重新命名key


       /// </summary>


       /// <param name="key">就的redis key</param>


       /// <param name="newKey">新的redis key</param>


       /// <returns></returns>


       public async Task<bool> KeyRenameAsync(string key, string newKey)


       {


           key = AddSysCustomKey(key);


           newKey = AddSysCustomKey(newKey);


           return await redis.KeyRenameAsync(key, newKey);


       }




       /// <summary>


       /// 设置Key的过期时间


       /// </summary>


       /// <param name="key">redis key</param>


       /// <param name="expiry">过期时间</param>


       /// <returns></returns>


       public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry = default(TimeSpan?))


       {


           key = AddSysCustomKey(key);


           return await redis.KeyExpireAsync(key, expiry);


       }


       #endregion




       #endregion




       #endregion




       #region 辅助方法




       /// <summary>


       /// 将对象转换成string字符串


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="value"></param>


       /// <returns></returns>


       protected string ConvertJson<T>(T value)


       {


           string result = value is string ? value.ToString() :


               JsonConvert.SerializeObject(value, Formatting.None);


           return result;


       }


       /// <summary>


       /// 将值反系列化成对象


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="value"></param>


       /// <returns></returns>


       protected T ConvertObj<T>(RedisValue value)


       {


           return value.IsNullOrEmpty ? default(T) : JsonConvert.DeserializeObject<T>(value);


       }




       /// <summary>


       /// 将值反系列化成对象集合


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="values"></param>


       /// <returns></returns>


       protected List<T> ConvetList<T>(RedisValue[] values)


       {


           List<T> result = new List<T>();


           foreach (var item in values)


           {


               var model = ConvertObj<T>(item);


               result.Add(model);


           }


           return result;


       }


       /// <summary>


       /// 将string类型的Key转换成 <see cref="RedisKey"/> 型的Key


       /// </summary>


       /// <param name="redisKeys"></param>


       /// <returns></returns>


       protected RedisKey[] ConvertRedisKeys(List<string> redisKeys) => redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray();




       /// <summary>


       /// 将string类型的Key转换成 <see cref="RedisKey"/> 型的Key


       /// </summary>


       /// <param name="redisKeys"></param>


       /// <returns></returns>


       protected RedisKey[] ConvertRedisKeys(params string[] redisKeys) => redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray();




       /// <summary>


       /// 将string类型的Key转换成 <see cref="RedisKey"/> 型的Key,并添加前缀字符串


       /// </summary>


       /// <param name="redisKeys"></param>


       /// <returns></returns>


       protected RedisKey[] ConvertRedisKeysAddSysCustomKey(params string[] redisKeys) => redisKeys.Select(redisKey => (RedisKey)AddSysCustomKey(redisKey)).ToArray();


       /// <summary>


       /// 将值集合转换成RedisValue集合


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="redisValues"></param>


       /// <returns></returns>


       protected RedisValue[] ConvertRedisValue<T>(params T[] redisValues) => redisValues.Select(o => (RedisValue)ConvertJson<T>(o)).ToArray();


       #endregion 辅助方法




   }




复制代码




Redis基本信息初始化辅助类


复制代码




   /// <summary>


   /// Redis基本信息初始化辅助类


   /// </summary>


   internal class RedisManager


   {


       //private static LogHelper log = LogHelper.LogInterface<RedisManager>();


       private static readonly object Locker = new object();


       private static ConnectionMultiplexer _instance;


       private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>();


       /// <summary>


       /// Redis保存的Key前缀,会自动添加到指定的Key名称前


       /// </summary>


       internal static readonly string RedisSysCustomKey = ConfigurationManager.AppSettings["RedisSysCustomKey"];


       /// <summary>


       /// 当前连接的Redis中的DataBase索引,默认0-16,可以在service.conf配置,最高64


       /// </summary>


       internal static readonly int RedisDataBaseIndex = int.Parse(ConfigurationManager.AppSettings["RedisDataBaseIndex"]);


       /// <summary>


       /// 当前连接的Redis中连接字符串,格式为:127.0.0.1:6379,allowadmin=true,passowrd=pwd


       /// </summary>


       internal static readonly string RedisHostConnection = ConfigurationManager.AppSettings["RedisHostConnection"];




       /// <summary>


       /// 单例获取


       /// </summary>


       public static ConnectionMultiplexer Instance


       {


           get


           {


               if (_instance == null)


               {


                   lock (Locker)


                   {


                       if (_instance == null || !_instance.IsConnected)


                       {


                           _instance = GetManager();


                       }


                   }


               }


               return _instance;


           }


       }




       /// <summary>


       /// 缓存获取


       /// </summary>


       /// <param name="connectionString"></param>


       /// <returns></returns>


       public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)


       {


           if (!ConnectionCache.ContainsKey(connectionString))


           {


               ConnectionCache[connectionString] = GetManager(connectionString);


           }


           return ConnectionCache[connectionString];


       }




       /// <summary>


       /// 内部方法,获取Redis连接


       /// </summary>


       /// <param name="connectionString"></param>


       /// <returns></returns>


       private static ConnectionMultiplexer GetManager(string connectionString = null)


       {


           connectionString = connectionString ?? RedisHostConnection;


           var connect = ConnectionMultiplexer.Connect(connectionString);




           //注册如下事件


           connect.ConnectionFailed += MuxerConnectionFailed;


           connect.ConnectionRestored += MuxerConnectionRestored;


           connect.ErrorMessage += MuxerErrorMessage;


           connect.ConfigurationChanged += MuxerConfigurationChanged;


           connect.HashSlotMoved += MuxerHashSlotMoved;


           connect.InternalError += MuxerInternalError;




           return connect;


       }




       #region 事件




       /// <summary>


       /// 配置更改时


       /// </summary>


       /// <param name="sender"></param>


       /// <param name="e"></param>


       private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)


       {


           //log.InfoAsync($"Configuration changed: {e.EndPoint}");


       }




       /// <summary>


       /// 发生错误时


       /// </summary>


       /// <param name="sender"></param>


       /// <param name="e"></param>


       private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)


       {


           //log.InfoAsync($"ErrorMessage: {e.Message}");


       }




       /// <summary>


       /// 重新建立连接之前的错误


       /// </summary>


       /// <param name="sender"></param>


       /// <param name="e"></param>


       private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)


       {


           //log.InfoAsync($"ConnectionRestored: {e.EndPoint}");


       }




       /// <summary>


       /// 连接失败 , 如果重新连接成功你将不会收到这个通知


       /// </summary>


       /// <param name="sender"></param>


       /// <param name="e"></param>


       private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)


       {


           //log.InfoAsync($"重新连接:Endpoint failed: {e.EndPoint},  {e.FailureType} , {(e.Exception == null ? "" : e.Exception.Message)}");


       }




       /// <summary>


       /// 更改集群


       /// </summary>


       /// <param name="sender"></param>


       /// <param name="e"></param>


       private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)


       {


           //log.InfoAsync($"HashSlotMoved:NewEndPoint{e.NewEndPoint}, OldEndPoint{e.OldEndPoint}");


       }




       /// <summary>


       /// redis类库错误


       /// </summary>


       /// <param name="sender"></param>


       /// <param name="e"></param>


       private static void MuxerInternalError(object sender, InternalErrorEventArgs e)


       {


           //log.InfoAsync($"InternalError:Message{ e.Exception.Message}");


       }




       #endregion 事件


   }




复制代码


String




redis 的string类型操作类


View Code




使用


复制代码




Console.WriteLine("*****************************************");


           {


               //key  value 都是string   假如是个对象呢?序列化一下


               //假如要修改某一个属性的值   读--反序列化--修改--序列化 memcached


               using (RedisStringService service = new RedisStringService())


               {


                   service.KeyFulsh();


                   service.StringSet("RedisStringService_key1", "RedisStringService_value1");


                   Console.WriteLine(service.StringGet("RedisStringService_key1"));


                   Console.WriteLine(service.StringGetSet("RedisStringService_key1", "RedisStringService_value2"));


                   Console.WriteLine(service.StringGet("RedisStringService_key1"));




                   service.StringAppend("RedisStringService_key1", "Append");


                   Console.WriteLine(service.StringGet("RedisStringService_key1"));


                   service.StringSet("RedisStringService_key1", "RedisStringService_value", new TimeSpan(0, 0, 0, 5));


                   Console.WriteLine(service.StringGet("RedisStringService_key1"));


                   Thread.Sleep(5000);


                   Console.WriteLine(service.StringGet("RedisStringService_key1"));


               }


           }




复制代码


Hashtable




redis 的Hash类型操作类


复制代码




   /// <summary>


   /// Hash:类似dictionary,通过索引快速定位到指定元素的,耗时均等,跟string的区别在于不用反序列化,直接修改某个字段


   /// string的话要么是 001:序列化整个实体


   ///           要么是 001_name:  001_pwd: 多个key-value


   /// Hash的话,一个hashid-{key:value;key:value;key:value;}


   /// 可以一次性查找实体,也可以单个,还可以单个修改


   /// </summary>


   public class RedisHashService : RedisBase


   {




       #region 构造函数




       /// <summary>


       /// 初始化Redis的Hash数据结构操作


       /// </summary>


       /// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>


       public RedisHashService(int? dbNum = null) :


           base(dbNum)


       { }


       #endregion




       #region 同步方法




       /// <summary>


       /// 判断某个数据是否已经被缓存


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <returns></returns>


       public bool HashExists(string key, string dataKey)


       {


           key = AddSysCustomKey(key);


           return base.redis.HashExists(key, dataKey);


       }




       /// <summary>


       /// 存储数据到hash表


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <param name="t"></param>


       /// <returns></returns>


       public bool HashSet<T>(string key, string dataKey, T t)


       {


           key = AddSysCustomKey(key);


           string json = ConvertJson(t);


           return base.redis.HashSet(key, dataKey, json);


       }




       /// <summary>


       /// 移除hash中的某值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <returns></returns>


       public bool HashDelete(string key, string dataKey)


       {


           key = AddSysCustomKey(key);


           return base.redis.HashDelete(key, dataKey);


       }




       /// <summary>


       /// 移除hash中的多个值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKeys"></param>


       /// <returns></returns>


       public long HashDelete(string key, params string[] dataKeys)


       {


           key = AddSysCustomKey(key);


           var newValues = dataKeys.Select(o => (RedisValue)o).ToArray();


           return base.redis.HashDelete(key, newValues);


       }




       /// <summary>


       /// 从hash表获取数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <returns></returns>


       public T HashGet<T>(string key, string dataKey)


       {


           key = AddSysCustomKey(key);


           string value = base.redis.HashGet(key, dataKey);


           return ConvertObj<T>(value);


       }




       /// <summary>


       /// 数字增长val,返回自增后的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <param name="val">可以为负</param>


       /// <returns>增长后的值</returns>


       public double HashIncrement(string key, string dataKey, double val = 1)


       {


           key = AddSysCustomKey(key);


           return base.redis.HashIncrement(key, dataKey, val);


       }




       /// <summary>


       /// 数字减少val,返回自减少的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <param name="val">可以为负</param>


       /// <returns>减少后的值</returns>


       public double HashDecrement(string key, string dataKey, double val = 1)


       {


           key = AddSysCustomKey(key);


           return base.redis.HashDecrement(key, dataKey, val);


       }




       /// <summary>


       /// 获取hashkey所有key名称


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public string[] HashKeys(string key)


       {


           key = AddSysCustomKey(key);


           RedisValue[] values = base.redis.HashKeys(key);


           return values.Select(o=>o.ToString()).ToArray();


       }




       /// <summary>


       /// 获取hashkey所有key与值,必须保证Key内的所有数据类型一致


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public Dictionary<string, T> HashGetAll<T>(string key)


       {


           key = AddSysCustomKey(key);


           var query = base.redis.HashGetAll(key);


           Dictionary<string, T> dic = new Dictionary<string, T>();


           foreach (var item in query)


           {


               dic.Add(item.Name, ConvertObj<T>(item.Value));


           }


           return dic;


       }




       #endregion 同步方法




       #region 异步方法




       /// <summary>


       /// 异步方法 判断某个数据是否已经被缓存


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <returns></returns>


       public async Task<bool> HashExistsAsync(string key, string dataKey)


       {


           key = AddSysCustomKey(key);


           return await base.redis.HashExistsAsync(key, dataKey);


       }




       /// <summary>


       /// 异步方法 存储数据到hash表


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <param name="t"></param>


       /// <returns></returns>


       public async Task<bool> HashSetAsync<T>(string key, string dataKey, T t)


       {


           key = AddSysCustomKey(key);


           string json = ConvertJson(t);


           return await base.redis.HashSetAsync(key, dataKey, json);


       }




       /// <summary>


       /// 异步方法 移除hash中的某值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <returns></returns>


       public async Task<bool> HashDeleteAsync(string key, string dataKey)


       {


           key = AddSysCustomKey(key);


           return await base.redis.HashDeleteAsync(key, dataKey);


       }




       /// <summary>


       /// 异步方法 移除hash中的多个值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKeys"></param>


       /// <returns></returns>


       public async Task<long> HashDeleteAsync(string key, params string[] dataKeys)


       {


           key = AddSysCustomKey(key);


           var newValues = dataKeys.Select(o => (RedisValue)o).ToArray();


           return await base.redis.HashDeleteAsync(key, newValues);


       }




       /// <summary>


       /// 异步方法 从hash表获取数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <returns></returns>


       public async Task<T> HashGetAsync<T>(string key, string dataKey)


       {


           key = AddSysCustomKey(key);


           string value = await base.redis.HashGetAsync(key, dataKey);


           return ConvertObj<T>(value);


       }




       /// <summary>


       /// 异步方法 数字增长val,返回自增后的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <param name="val">可以为负</param>


       /// <returns>增长后的值</returns>


       public async Task<double> HashIncrementAsync(string key, string dataKey, double val = 1)


       {


           key = AddSysCustomKey(key);


           return await base.redis.HashIncrementAsync(key, dataKey, val);


       }




       /// <summary>


       /// 异步方法 数字减少val,返回自减少的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="dataKey"></param>


       /// <param name="val">可以为负</param>


       /// <returns>减少后的值</returns>


       public async Task<double> HashDecrementAsync(string key, string dataKey, double val = 1)


       {


           key = AddSysCustomKey(key);


           return await base.redis.HashDecrementAsync(key, dataKey, val);


       }




       /// <summary>


       /// 异步方法 获取hashkey所有key名称


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<string[]> HashKeysAsync(string key)


       {


           key = AddSysCustomKey(key);


           RedisValue[] values = await base.redis.HashKeysAsync(key);


           return values.Select(o => o.ToString()).ToArray();


       }




       /// <summary>


       /// 获取hashkey所有key与值,必须保证Key内的所有数据类型一致


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<Dictionary<string, T>> HashGetAllAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var query = await base.redis.HashGetAllAsync(key);


           Dictionary<string, T> dic = new Dictionary<string, T>();


           foreach (var item in query)


           {


               dic.Add(item.Name, ConvertObj<T>(item.Value));


           }


           return dic;


       }




       #endregion 异步方法




   }




复制代码


Set




redis 的Set类型操作类


复制代码




   /// <summary>


   /// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据


   /// 1.共同好友、二度好友


   /// 2.利用唯一性,可以统计访问网站的所有独立 IP


   /// </summary>


   public class RedisSetService : RedisBase


   {


       #region 构造函数




       /// <summary>


       /// 初始化Redis的Set无序数据结构操作


       /// </summary>


       /// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>


       public RedisSetService(int? dbNum = null) :


           base(dbNum)


       { }


       #endregion




       #region 同步方法


       /// <summary>


       /// 在Key集合中添加一个value值


       /// </summary>


       /// <typeparam name="T">数据类型</typeparam>


       /// <param name="key">Key名称</param>


       /// <param name="value">值</param>


       /// <returns></returns>


       public bool SetAdd<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return base.redis.SetAdd(key, jValue);


       }


       /// <summary>


       /// 在Key集合中添加多个value值


       /// </summary>


       /// <typeparam name="T">数据类型</typeparam>


       /// <param name="key">Key名称</param>


       /// <param name="value">值列表</param>


       /// <returns></returns>


       public long SetAdd<T>(string key, List<T> value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());


           return base.redis.SetAdd(key, valueList);


       }




       /// <summary>


       /// 获取key集合值的数量


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public long SetLength(string key)


       {


           key = AddSysCustomKey(key);


           return base.redis.SetLength(key);


       }




       /// <summary>


       /// 判断Key集合中是否包含指定的值


       /// </summary>


       /// <typeparam name="T">值类型</typeparam>


       /// <param name="key"></param>


       /// <param name="value">要判断是值</param>


       /// <returns></returns>


       public bool SetContains<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return base.redis.SetContains(key, jValue);


       }




       /// <summary>


       /// 随机获取key集合中的一个值


       /// </summary>


       /// <typeparam name="T">数据类型</typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public T SetRandomMember<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.SetRandomMember(key);


           return ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 获取key所有值的集合


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public List<T> SetMembers<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.SetMembers(key);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 删除key集合中指定的value


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public long SetRemove<T>(string key, params T[] value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value);


           return base.redis.SetRemove(key, valueList);


       }




       /// <summary>


       /// 随机删除key集合中的一个值,并返回该值


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public T SetPop<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.SetPop(key);


           return ConvertObj<T>(rValue);


       }






       /// <summary>


       /// 获取几个集合的并集


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public List<T> SetCombineUnion<T>(params string[] keys)


       {


           return _SetCombine<T>(SetOperation.Union, keys);


       }


       /// <summary>


       /// 获取几个集合的交集


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public List<T> SetCombineIntersect<T>(params string[] keys)


       {


           return _SetCombine<T>(SetOperation.Intersect, keys);


       }


       /// <summary>


       /// 获取几个集合的差集


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public List<T> SetCombineDifference<T>(params string[] keys)


       {


           return _SetCombine<T>(SetOperation.Difference, keys);


       }




       /// <summary>


       /// 获取几个集合的并集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public long SetCombineUnionAndStore(string destination, params string[] keys)


       {


           return _SetCombineAndStore(SetOperation.Union, destination, keys);


       }


       /// <summary>


       /// 获取几个集合的交集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public long SetCombineIntersectAndStore(string destination, params string[] keys)


       {


           return _SetCombineAndStore(SetOperation.Intersect, destination, keys);


       }


       /// <summary>


       /// 获取几个集合的差集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public long SetCombineDifferenceAndStore(string destination, params string[] keys)


       {


           return _SetCombineAndStore(SetOperation.Difference, destination, keys);


       }


       #endregion




       #region 异步方法


       /// <summary>


       /// 在Key集合中添加一个value值


       /// </summary>


       /// <typeparam name="T">数据类型</typeparam>


       /// <param name="key">Key名称</param>


       /// <param name="value">值</param>


       /// <returns></returns>


       public async Task<bool> SetAddAsync<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return await base.redis.SetAddAsync(key, jValue);


       }


       /// <summary>


       /// 在Key集合中添加多个value值


       /// </summary>


       /// <typeparam name="T">数据类型</typeparam>


       /// <param name="key">Key名称</param>


       /// <param name="value">值列表</param>


       /// <returns></returns>


       public async Task<long> SetAddAsync<T>(string key, List<T> value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());


           return await base.redis.SetAddAsync(key, valueList);


       }




       /// <summary>


       /// 获取key集合值的数量


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<long> SetLengthAsync(string key)


       {


           key = AddSysCustomKey(key);


           return await base.redis.SetLengthAsync(key);


       }




       /// <summary>


       /// 判断Key集合中是否包含指定的值


       /// </summary>


       /// <typeparam name="T">值类型</typeparam>


       /// <param name="key"></param>


       /// <param name="value">要判断是值</param>


       /// <returns></returns>


       public async Task<bool> SetContainsAsync<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return await base.redis.SetContainsAsync(key, jValue);


       }




       /// <summary>


       /// 随机获取key集合中的一个值


       /// </summary>


       /// <typeparam name="T">数据类型</typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<T> SetRandomMemberAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.SetRandomMemberAsync(key);


           return ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 获取key所有值的集合


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<List<T>> SetMembersAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.SetMembersAsync(key);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 删除key集合中指定的value


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<long> SetRemoveAsync<T>(string key, params T[] value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value);


           return await base.redis.SetRemoveAsync(key, valueList);


       }




       /// <summary>


       /// 随机删除key集合中的一个值,并返回该值


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<T> SetPopAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.SetPopAsync(key);


           return ConvertObj<T>(rValue);


       }






       /// <summary>


       /// 获取几个集合的并集


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<List<T>> SetCombineUnionAsync<T>(params string[] keys)


       {


           return await _SetCombineAsync<T>(SetOperation.Union, keys);


       }


       /// <summary>


       /// 获取几个集合的交集


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<List<T>> SetCombineIntersectAsync<T>(params string[] keys)


       {


           return await _SetCombineAsync<T>(SetOperation.Intersect, keys);


       }


       /// <summary>


       /// 获取几个集合的差集


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<List<T>> SetCombineDifferenceAsync<T>(params string[] keys)


       {


           return await _SetCombineAsync<T>(SetOperation.Difference, keys);


       }








       /// <summary>


       /// 获取几个集合的并集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<long> SetCombineUnionAndStoreAsync(string destination, params string[] keys)


       {


           return await _SetCombineAndStoreAsync(SetOperation.Union, destination, keys);


       }


       /// <summary>


       /// 获取几个集合的交集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<long> SetCombineIntersectAndStoreAsync(string destination, params string[] keys)


       {


           return await _SetCombineAndStoreAsync(SetOperation.Intersect, destination, keys);


       }


       /// <summary>


       /// 获取几个集合的差集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<long> SetCombineDifferenceAndStoreAsync(string destination, params string[] keys)


       {


           return await _SetCombineAndStoreAsync(SetOperation.Difference, destination, keys);


       }




       #endregion




       #region 内部辅助方法


       /// <summary>


       /// 获取几个集合的交叉并集合


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="operation">Union:并集  Intersect:交集  Difference:差集  详见 <see cref="SetOperation"/></param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       private List<T> _SetCombine<T>(SetOperation operation, params string[] keys)


       {


           RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);


           var rValue = base.redis.SetCombine(operation, keyList);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 获取几个集合的交叉并集合,并保存到一个新Key中


       /// </summary>


       /// <param name="operation">Union:并集  Intersect:交集  Difference:差集  详见 <see cref="SetOperation"/></param>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       private long _SetCombineAndStore(SetOperation operation, string destination, params string[] keys)


       {


           destination = AddSysCustomKey(destination);


           RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);


           return base.redis.SetCombineAndStore(operation, destination, keyList);


       }


       /// <summary>


       /// 获取几个集合的交叉并集合


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="operation">Union:并集  Intersect:交集  Difference:差集  详见 <see cref="SetOperation"/></param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       private async Task<List<T>> _SetCombineAsync<T>(SetOperation operation, params string[] keys)


       {


           RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);


           var rValue = await base.redis.SetCombineAsync(operation, keyList);


           return ConvetList<T>(rValue);


       }


       /// <summary>


       /// 获取几个集合的交叉并集合,并保存到一个新Key中


       /// </summary>


       /// <param name="operation">Union:并集  Intersect:交集  Difference:差集  详见 <see cref="SetOperation"/></param>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       private async Task<long> _SetCombineAndStoreAsync(SetOperation operation, string destination, params string[] keys)


       {


           destination = AddSysCustomKey(destination);


           RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);


           return await base.redis.SetCombineAndStoreAsync(operation, destination, keyList);


       }




       #endregion




   }




复制代码


ZSet




redis 的zset类型操作类


复制代码




   /// <summary>


   /// Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列


   /// 1.带有权重的元素,比如一个游戏的用户得分排行榜


   /// 2.比较复杂的数据结构,一般用到的场景不算太多


   /// </summary>


   public class RedisSortedSetService : RedisBase


   {


       #region 构造函数




       /// <summary>


       /// 初始化Redis的SortedSet有序数据结构操作


       /// </summary>


       /// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>


       public RedisSortedSetService(int? dbNum = null) :


           base(dbNum)


       { }


       #endregion




       #region 同步方法




       /// <summary>


       /// 添加一个值到Key


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="score">排序分数,为空将获取集合中最大score加1</param>


       /// <returns></returns>


       public bool SortedSetAdd<T>(string key, T value, double? score = null)


       {


           key = AddSysCustomKey(key);


           double scoreNum = score ?? _GetScore(key);


           return base.redis.SortedSetAdd(key, ConvertJson<T>(value), scoreNum);


       }




       /// <summary>


       /// 添加一个集合到Key


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="score">排序分数,为空将获取集合中最大score加1</param>


       /// <returns></returns>


       public long SortedSetAdd<T>(string key, List<T> value, double? score = null)


       {


           key = AddSysCustomKey(key);


           double scoreNum = score ?? _GetScore(key);


           SortedSetEntry[] rValue = value.Select(o => new SortedSetEntry(ConvertJson<T>(o), scoreNum++)).ToArray();


           return base.redis.SortedSetAdd(key, rValue);


       }




       /// <summary>


       /// 获取集合中的数量


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public long SortedSetLength(string key)


       {


           key = AddSysCustomKey(key);


           return redis.SortedSetLength(key);


       }




       /// <summary>


       /// 获取指定起始值到结束值的集合数量


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="startValue">起始值</param>


       /// <param name="endValue">结束值</param>


       /// <returns></returns>


       public long SortedSetLengthByValue<T>(string key, T startValue, T endValue)


       {


           key = AddSysCustomKey(key);


           var sValue = ConvertJson<T>(startValue);


           var eValue = ConvertJson<T>(endValue);


           return redis.SortedSetLengthByValue(key, sValue, eValue);


       }




       /// <summary>


       /// 获取指定Key的排序Score值


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public double? SortedSetScore<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertJson<T>(value);


           return redis.SortedSetScore(key, rValue);


       }




       /// <summary>


       /// 获取指定Key中最小Score值


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public double SortedSetMinScore(string key)


       {


           key = AddSysCustomKey(key);


           double dValue = 0;


           var rValue = base.redis.SortedSetRangeByRankWithScores(key, 0, 0, Order.Ascending).FirstOrDefault();


           dValue = rValue != null ? rValue.Score : 0;


           return dValue;


       }




       /// <summary>


       /// 获取指定Key中最大Score值


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public double SortedSetMaxScore(string key)


       {


           key = AddSysCustomKey(key);


           double dValue = 0;


           var rValue = base.redis.SortedSetRangeByRankWithScores(key, 0, 0, Order.Descending).FirstOrDefault();


           dValue = rValue != null ? rValue.Score : 0;


           return dValue;


       }




       /// <summary>


       /// 删除Key中指定的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="value"></param>


       public long SortedSetRemove<T>(string key, params T[] value)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertRedisValue<T>(value);


           return base.redis.SortedSetRemove(key, rValue);


       }




       /// <summary>


       /// 删除指定起始值到结束值的数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="startValue">起始值</param>


       /// <param name="endValue">结束值</param>


       /// <returns></returns>


       public long SortedSetRemoveRangeByValue<T>(string key, T startValue, T endValue)


       {


           key = AddSysCustomKey(key);


           var sValue = ConvertJson<T>(startValue);


           var eValue = ConvertJson<T>(endValue);


           return base.redis.SortedSetRemoveRangeByValue(key, sValue, eValue);


       }




       /// <summary>


       /// 删除 从 start 开始的 stop 条数据


       /// </summary>


       /// <param name="key"></param>


       /// <param name="start"></param>


       /// <param name="stop"></param>


       /// <returns></returns>


       public long SortedSetRemoveRangeByRank(string key, long start, long stop)


       {


           key = AddSysCustomKey(key);


           return base.redis.SortedSetRemoveRangeByRank(key, start, stop);


       }




       /// <summary>


       /// 根据排序分数Score,删除从 start 开始的 stop 条数据


       /// </summary>


       /// <param name="key"></param>


       /// <param name="start"></param>


       /// <param name="stop"></param>


       /// <returns></returns>


       public long SortedSetRemoveRangeByScore(string key, double start, double stop)


       {


           key = AddSysCustomKey(key);


           return base.redis.SortedSetRemoveRangeByScore(key, start, stop);


       }




       /// <summary>


       /// 获取从 start 开始的 stop 条数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public List<T> SortedSetRangeByRank<T>(string key, long start = 0, long stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = base.redis.SortedSetRangeByRank(key, start, stop, orderBy);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public Dictionary<T, double> SortedSetRangeByRankWithScores<T>(string key, long start = 0, long stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = base.redis.SortedSetRangeByRankWithScores(key, start, stop, orderBy);


           Dictionary<T, double> dicList = new Dictionary<T, double>();


           foreach (var item in rValue)


           {


               dicList.Add(ConvertObj<T>(item.Element), item.Score);


           }


           return dicList;


       }




       /// <summary>


       ///  根据Score排序 获取从 start 开始的 stop 条数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public List<T> SortedSetRangeByScore<T>(string key, double start = 0, double stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = base.redis.SortedSetRangeByScore(key, start, stop, Exclude.None, orderBy);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 根据Score排序  获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public Dictionary<T, double> SortedSetRangeByScoreWithScores<T>(string key, double start = 0, double stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = base.redis.SortedSetRangeByScoreWithScores(key, start, stop, Exclude.None, orderBy);


           Dictionary<T, double> dicList = new Dictionary<T, double>();


           foreach (var item in rValue)


           {


               dicList.Add(ConvertObj<T>(item.Element), item.Score);


           }


           return dicList;


       }




       /// <summary>


       /// 获取指定起始值到结束值的数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="startValue">起始值</param>


       /// <param name="endValue">结束值</param>


       /// <returns></returns>


       public List<T> SortedSetRangeByValue<T>(string key, T startValue, T endValue)


       {


           key = AddSysCustomKey(key);


           var sValue = ConvertJson<T>(startValue);


           var eValue = ConvertJson<T>(endValue);


           var rValue = base.redis.SortedSetRangeByValue(key, sValue, eValue);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 获取几个集合的并集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public long SortedSetCombineUnionAndStore(string destination, params string[] keys)


       {


           return _SortedSetCombineAndStore(SetOperation.Union, destination, keys);


       }




       /// <summary>


       /// 获取几个集合的交集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public long SortedSetCombineIntersectAndStore(string destination, params string[] keys)


       {


           return _SortedSetCombineAndStore(SetOperation.Intersect, destination, keys);


       }






       //交集似乎并不支持


       ///// <summary>


       ///// 获取几个集合的差集,并保存到一个新Key中


       ///// </summary>


       ///// <param name="destination">保存的新Key名称</param>


       ///// <param name="keys">要操作的Key集合</param>


       ///// <returns></returns>


       //public long SortedSetCombineDifferenceAndStore(string destination, params string[] keys)


       //{


       //    return _SortedSetCombineAndStore(SetOperation.Difference, destination, keys);


       //}








       /// <summary>


       /// 修改指定Key和值的Scores在原值上减去scores,并返回最终Scores


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="scores"></param>


       /// <returns></returns>


       public double SortedSetDecrement<T>(string key, T value, double scores)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertJson<T>(value);


           return redis.SortedSetDecrement(key, rValue, scores);


       }




       /// <summary>


       /// 修改指定Key和值的Scores在原值上增加scores,并返回最终Scores


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="scores"></param>


       /// <returns></returns>


       public double SortedSetIncrement<T>(string key, T value, double scores)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertJson<T>(value);


           return redis.SortedSetIncrement(key, rValue, scores);


       }








       #endregion




       #region 异步方法




       /// <summary>


       /// 添加一个值到Key


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="score">排序分数,为空将获取集合中最大score加1</param>


       /// <returns></returns>


       public async Task<bool> SortedSetAddAsync<T>(string key, T value, double? score = null)


       {


           key = AddSysCustomKey(key);


           double scoreNum = score ?? _GetScore(key);


           return await base.redis.SortedSetAddAsync(key, ConvertJson<T>(value), scoreNum);


       }




       /// <summary>


       /// 添加一个集合到Key


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="score">排序分数,为空将获取集合中最大score加1</param>


       /// <returns></returns>


       public async Task<long> SortedSetAddAsync<T>(string key, List<T> value, double? score = null)


       {


           key = AddSysCustomKey(key);


           double scoreNum = score ?? _GetScore(key);


           SortedSetEntry[] rValue = value.Select(o => new SortedSetEntry(ConvertJson<T>(o), scoreNum++)).ToArray();


           return await base.redis.SortedSetAddAsync(key, rValue);


       }




       /// <summary>


       /// 获取集合中的数量


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<long> SortedSetLengthAsync(string key)


       {


           key = AddSysCustomKey(key);


           return await redis.SortedSetLengthAsync(key);


       }




       /// <summary>


       /// 获取指定起始值到结束值的集合数量


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="startValue">起始值</param>


       /// <param name="endValue">结束值</param>


       /// <returns></returns>


       public async Task<long> SortedSetLengthByValueAsync<T>(string key, T startValue, T endValue)


       {


           key = AddSysCustomKey(key);


           var sValue = ConvertJson<T>(startValue);


           var eValue = ConvertJson<T>(endValue);


           return await redis.SortedSetLengthByValueAsync(key, sValue, eValue);


       }




       /// <summary>


       /// 获取指定Key的排序Score值


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<double?> SortedSetScoreAsync<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertJson<T>(value);


           return await redis.SortedSetScoreAsync(key, rValue);


       }




       /// <summary>


       /// 获取指定Key中最小Score值


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<double> SortedSetMinScoreAsync(string key)


       {


           key = AddSysCustomKey(key);


           double dValue = 0;


           var rValue = (await base.redis.SortedSetRangeByRankWithScoresAsync(key, 0, 0, Order.Ascending)).FirstOrDefault();


           dValue = rValue != null ? rValue.Score : 0;


           return dValue;


       }




       /// <summary>


       /// 获取指定Key中最大Score值


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<double> SortedSetMaxScoreAsync(string key)


       {


           key = AddSysCustomKey(key);


           double dValue = 0;


           var rValue = (await base.redis.SortedSetRangeByRankWithScoresAsync(key, 0, 0, Order.Descending)).FirstOrDefault();


           dValue = rValue != null ? rValue.Score : 0;


           return dValue;


       }




       /// <summary>


       /// 删除Key中指定的值


       /// </summary>


       /// <param name="key"></param>


       /// <param name="value"></param>


       public async Task<long> SortedSetRemoveAsync<T>(string key, params T[] value)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertRedisValue<T>(value);


           return await base.redis.SortedSetRemoveAsync(key, rValue);


       }




       /// <summary>


       /// 删除指定起始值到结束值的数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="startValue">起始值</param>


       /// <param name="endValue">结束值</param>


       /// <returns></returns>


       public async Task<long> SortedSetRemoveRangeByValueAsync<T>(string key, T startValue, T endValue)


       {


           key = AddSysCustomKey(key);


           var sValue = ConvertJson<T>(startValue);


           var eValue = ConvertJson<T>(endValue);


           return await base.redis.SortedSetRemoveRangeByValueAsync(key, sValue, eValue);


       }




       /// <summary>


       /// 删除 从 start 开始的 stop 条数据


       /// </summary>


       /// <param name="key"></param>


       /// <param name="start"></param>


       /// <param name="stop"></param>


       /// <returns></returns>


       public async Task<long> SortedSetRemoveRangeByRankAsync(string key, long start, long stop)


       {


           key = AddSysCustomKey(key);


           return await base.redis.SortedSetRemoveRangeByRankAsync(key, start, stop);


       }




       /// <summary>


       /// 根据排序分数Score,删除从 start 开始的 stop 条数据


       /// </summary>


       /// <param name="key"></param>


       /// <param name="start"></param>


       /// <param name="stop"></param>


       /// <returns></returns>


       public async Task<long> SortedSetRemoveRangeByScoreAsync(string key, double start, double stop)


       {


           key = AddSysCustomKey(key);


           return await base.redis.SortedSetRemoveRangeByScoreAsync(key, start, stop);


       }




       /// <summary>


       /// 获取从 start 开始的 stop 条数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = await base.redis.SortedSetRangeByRankAsync(key, start, stop, orderBy);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public async Task<Dictionary<T, double>> SortedSetRangeByRankWithScoresAsync<T>(string key, long start = 0, long stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = await base.redis.SortedSetRangeByRankWithScoresAsync(key, start, stop, orderBy);


           Dictionary<T, double> dicList = new Dictionary<T, double>();


           foreach (var item in rValue)


           {


               dicList.Add(ConvertObj<T>(item.Element), item.Score);


           }


           return dicList;


       }




       /// <summary>


       ///  根据Score排序 获取从 start 开始的 stop 条数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public async Task<List<T>> SortedSetRangeByScoreAsync<T>(string key, double start = 0, double stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = await base.redis.SortedSetRangeByScoreAsync(key, start, stop, Exclude.None, orderBy);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 根据Score排序  获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="start">起始数</param>


       /// <param name="stop">-1表示到结束,0为1条</param>


       /// <param name="desc">是否按降序排列</param>


       /// <returns></returns>


       public async Task<Dictionary<T, double>> SortedSetRangeByScoreWithScoresAsync<T>(string key, double start = 0, double stop = -1, bool desc = false)


       {


           key = AddSysCustomKey(key);


           Order orderBy = desc ? Order.Descending : Order.Ascending;


           var rValue = await base.redis.SortedSetRangeByScoreWithScoresAsync(key, start, stop, Exclude.None, orderBy);


           Dictionary<T, double> dicList = new Dictionary<T, double>();


           foreach (var item in rValue)


           {


               dicList.Add(ConvertObj<T>(item.Element), item.Score);


           }


           return dicList;


       }




       /// <summary>


       /// 获取指定起始值到结束值的数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="startValue">起始值</param>


       /// <param name="endValue">结束值</param>


       /// <returns></returns>


       public async Task<List<T>> SortedSetRangeByValueAsync<T>(string key, T startValue, T endValue)


       {


           key = AddSysCustomKey(key);


           var sValue = ConvertJson<T>(startValue);


           var eValue = ConvertJson<T>(endValue);


           var rValue = await base.redis.SortedSetRangeByValueAsync(key, sValue, eValue);


           return ConvetList<T>(rValue);


       }




       /// <summary>


       /// 获取几个集合的并集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<long> SortedSetCombineUnionAndStoreAsync(string destination, params string[] keys)


       {


           return await _SortedSetCombineAndStoreAsync(SetOperation.Union, destination, keys);


       }




       /// <summary>


       /// 获取几个集合的交集,并保存到一个新Key中


       /// </summary>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       public async Task<long> SortedSetCombineIntersectAndStoreAsync(string destination, params string[] keys)


       {


           return await _SortedSetCombineAndStoreAsync(SetOperation.Intersect, destination, keys);


       }




       ///// <summary>


       ///// 获取几个集合的差集,并保存到一个新Key中


       ///// </summary>


       ///// <param name="destination">保存的新Key名称</param>


       ///// <param name="keys">要操作的Key集合</param>


       ///// <returns></returns>


       //public async Task<long> SortedSetCombineDifferenceAndStoreAsync(string destination, params string[] keys)


       //{


       //    return await _SortedSetCombineAndStoreAsync(SetOperation.Difference, destination, keys);


       //}




       /// <summary>


       /// 修改指定Key和值的Scores在原值上减去scores,并返回最终Scores


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="scores"></param>


       /// <returns></returns>


       public async Task<double> SortedSetDecrementAsync<T>(string key, T value, double scores)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertJson<T>(value);


           return await base.redis.SortedSetDecrementAsync(key, rValue, scores);


       }




       /// <summary>


       /// 修改指定Key和值的Scores在原值上增加scores,并返回最终Scores


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <param name="scores"></param>


       /// <returns></returns>


       public async Task<double> SortedSetIncrementAsync<T>(string key, T value, double scores)


       {


           key = AddSysCustomKey(key);


           var rValue = ConvertJson<T>(value);


           return await base.redis.SortedSetIncrementAsync(key, rValue, scores);


       }








       #endregion




       #region 内部辅助方法


       /// <summary>


       /// 获取指定Key中最大Score值,


       /// </summary>


       /// <param name="key">key名称,注意要先添加上Key前缀</param>


       /// <returns></returns>


       private double _GetScore(string key)


       {


           double dValue = 0;


           var rValue = base.redis.SortedSetRangeByRankWithScores(key, 0, 0, Order.Descending).FirstOrDefault();


           dValue = rValue != null ? rValue.Score : 0;


           return dValue + 1;


       }




       /// <summary>


       /// 获取几个集合的交叉并集合,并保存到一个新Key中


       /// </summary>


       /// <param name="operation">Union:并集  Intersect:交集  Difference:差集  详见 <see cref="SetOperation"/></param>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       private long _SortedSetCombineAndStore(SetOperation operation, string destination, params string[] keys)


       {


           #region 查看源码,似乎并不支持Difference


           //RedisCommand command;


           //if (operation != SetOperation.Union)


           //{


           //    if (operation != SetOperation.Intersect)


           //    {


           //        throw new ArgumentOutOfRangeException("operation");


           //    }


           //    command = RedisCommand.ZINTERSTORE;


           //}


           //else


           //{


           //    command = RedisCommand.ZUNIONSTORE;


           //}


           #endregion




           destination = AddSysCustomKey(destination);


           RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);


           var rValue = base.redis.SortedSetCombineAndStore(operation, destination, keyList);


           return rValue;




       }




       /// <summary>


       /// 获取几个集合的交叉并集合,并保存到一个新Key中


       /// </summary>


       /// <param name="operation">Union:并集  Intersect:交集  Difference:差集  详见 <see cref="SetOperation"/></param>


       /// <param name="destination">保存的新Key名称</param>


       /// <param name="keys">要操作的Key集合</param>


       /// <returns></returns>


       private async Task<long> _SortedSetCombineAndStoreAsync(SetOperation operation, string destination, params string[] keys)


       {


           destination = AddSysCustomKey(destination);


           RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);


           var rValue = await base.redis.SortedSetCombineAndStoreAsync(operation, destination, keyList);


           return rValue;


       }




       #endregion


   }




复制代码


List




redis 的List类型操作类


复制代码




   /// <summary>


   /// Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,


   /// Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。  


   /// 一般是左进右出或者右进左出


   /// </summary>


   public class RedisListService : RedisBase


   {


       #region 构造函数




       /// <summary>


       /// 初始化Redis的List数据结构操作


       /// </summary>


       /// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>


       public RedisListService(int? dbNum = null) :


           base(dbNum)


       { }


       #endregion




       #region 同步方法


       /// <summary>


       /// 从左侧向list中添加一个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public long ListLeftPush<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return base.redis.ListLeftPush(key, jValue);


       }




       /// <summary>


       /// 从左侧向list中添加多个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public long ListLeftPush<T>(string key, List<T> value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());


           return base.redis.ListLeftPush(key, valueList);


       }




       /// <summary>


       /// 从右侧向list中添加一个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public long ListRightPush<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return base.redis.ListRightPush(key, jValue);


       }




       /// <summary>


       /// 从右侧向list中添加多个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public long ListRightPush<T>(string key, List<T> value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());


           return base.redis.ListRightPush(key, valueList);


       }




       /// <summary>


       /// 从左侧向list中取出一个值并从list中删除


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public T ListLeftPop<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.ListLeftPop(key);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 从右侧向list中取出一个值并从list中删除


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public T ListRightPop<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.ListRightPop(key);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 从key的List中右侧取出一个值,并从左侧添加到destination集合中,且返回该数据对象


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key">要取出数据的List名称</param>


       /// <param name="destination">要添加到的List名称</param>


       /// <returns></returns>


       public T ListRightPopLeftPush<T>(string key, string destination)


       {


           key = AddSysCustomKey(key);


           destination = AddSysCustomKey(destination);


           var rValue = base.redis.ListRightPopLeftPush(key, destination);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 在key的List指定值pivot之后插入value,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="pivot">索引值</param>


       /// <param name="value">要插入的值</param>


       /// <returns></returns>


       public long ListInsertAfter<T>(string key, T pivot, T value)


       {


           key = AddSysCustomKey(key);


           string pValue = ConvertJson(pivot);


           string jValue = ConvertJson(value);


           return base.redis.ListInsertAfter(key, pValue, jValue);


       }




       /// <summary>


       /// 在key的List指定值pivot之前插入value,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="pivot">索引值</param>


       /// <param name="value">要插入的值</param>


       /// <returns></returns>


       public long ListInsertBefore<T>(string key, T pivot, T value)


       {


           key = AddSysCustomKey(key);


           string pValue = ConvertJson(pivot);


           string jValue = ConvertJson(value);


           return base.redis.ListInsertBefore(key, pValue, jValue);


       }




       /// <summary>


       /// 从key的list中取出所有数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public List<T> ListRange<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.ListRange(key);


           return base.ConvetList<T>(rValue);


       }




       /// <summary>


       /// 从key的List获取指定索引的值


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="index"></param>


       /// <returns></returns>


       public T ListGetByIndex<T>(string key, long index)


       {


           key = AddSysCustomKey(key);


           var rValue = base.redis.ListGetByIndex(key, index);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 获取key的list中数据个数


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public long ListLength(string key)


       {


           key = AddSysCustomKey(key);


           return base.redis.ListLength(key);


       }




       /// <summary>


       /// 从key的List中移除指定的值,返回删除个数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public long ListRemove<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return base.redis.ListRemove(key, jValue);


       }


       #endregion




       #region 异步方法


       /// <summary>


       /// 从左侧向list中添加一个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<long> ListLeftPushAsync<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return await base.redis.ListLeftPushAsync(key, jValue);


       }




       /// <summary>


       /// 从左侧向list中添加多个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<long> ListLeftPushAsync<T>(string key, List<T> value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());


           return await base.redis.ListLeftPushAsync(key, valueList);


       }




       /// <summary>


       /// 从右侧向list中添加一个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<long> ListRightPushAsync<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return await base.redis.ListRightPushAsync(key, jValue);


       }




       /// <summary>


       /// 从右侧向list中添加多个值,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<long> ListRightPushAsync<T>(string key, List<T> value)


       {


           key = AddSysCustomKey(key);


           RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());


           return await base.redis.ListRightPushAsync(key, valueList);


       }




       /// <summary>


       /// 从左侧向list中取出一个值并从list中删除


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<T> ListLeftPopAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.ListLeftPopAsync(key);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 从右侧向list中取出一个值并从list中删除


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<T> ListRightPopAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.ListRightPopAsync(key);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 从key的List中右侧取出一个值,并从左侧添加到destination集合中,且返回该数据对象


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key">要取出数据的List名称</param>


       /// <param name="destination">要添加到的List名称</param>


       /// <returns></returns>


       public async Task<T> ListRightPopLeftPushAsync<T>(string key, string destination)


       {


           key = AddSysCustomKey(key);


           destination = AddSysCustomKey(destination);


           var rValue = await base.redis.ListRightPopLeftPushAsync(key, destination);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 在key的List指定值pivot之后插入value,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="pivot">索引值</param>


       /// <param name="value">要插入的值</param>


       /// <returns></returns>


       public async Task<long> ListInsertAfterAsync<T>(string key, T pivot, T value)


       {


           key = AddSysCustomKey(key);


           string pValue = ConvertJson(pivot);


           string jValue = ConvertJson(value);


           return await  base.redis.ListInsertAfterAsync(key, pValue, jValue);


       }




       /// <summary>


       /// 在key的List指定值pivot之前插入value,返回集合总数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="pivot">索引值</param>


       /// <param name="value">要插入的值</param>


       /// <returns></returns>


       public async Task<long> ListInsertBeforeAsync<T>(string key, T pivot, T value)


       {


           key = AddSysCustomKey(key);


           string pValue = ConvertJson(pivot);


           string jValue = ConvertJson(value);


           return await  base.redis.ListInsertBeforeAsync(key, pValue, jValue);


       }




       /// <summary>


       /// 从key的list中取出所有数据


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<List<T>> ListRangeAsync<T>(string key)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.ListRangeAsync(key);


           return base.ConvetList<T>(rValue);


       }




       /// <summary>


       /// 从key的List获取指定索引的值


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="index"></param>


       /// <returns></returns>


       public async Task<T> ListGetByIndexAsync<T>(string key, long index)


       {


           key = AddSysCustomKey(key);


           var rValue = await base.redis.ListGetByIndexAsync(key, index);


           return base.ConvertObj<T>(rValue);


       }




       /// <summary>


       /// 获取key的list中数据个数


       /// </summary>


       /// <param name="key"></param>


       /// <returns></returns>


       public async Task<long> ListLengthAsync(string key)


       {


           key = AddSysCustomKey(key);


           return await base.redis.ListLengthAsync(key);


       }




       /// <summary>


       /// 从key的List中移除指定的值,返回删除个数


       /// </summary>


       /// <typeparam name="T"></typeparam>


       /// <param name="key"></param>


       /// <param name="value"></param>


       /// <returns></returns>


       public async Task<long> ListRemoveAsync<T>(string key, T value)


       {


           key = AddSysCustomKey(key);


           string jValue = ConvertJson(value);


           return await base.redis.ListRemoveAsync(key, jValue);


       }


       #endregion


   }




复制代码




使用


复制代码




Console.WriteLine("*****************************************");


           {


               using (RedisListService service = new RedisListService())


               {


                    service.KeyFulsh();




                   List<string> stringList = new List<string>();


                   for (int i = 0; i < 10; i++)


                   {


                       stringList.Add(string.Format($"放入任务{i}"));


                   }




                   service.ListLeftPush("test", "这是一个学生1");


                   service.ListLeftPush("test", "这是一个学生2");


                   service.ListLeftPush("test", "这是一个学生3");


                   service.ListLeftPush("test", "这是一个学生4");


                   service.ListLeftPush("test", "这是一个学生5");


                   service.ListLeftPush("test", "这是一个学生6");




                   service.ListLeftPush("task", stringList);




                   Console.WriteLine(service.ListLength("test"));


                   Console.WriteLine(service.ListLength("task"));


                   var list = service.ListRange<string>("test");




                   Action act = new Action(() =>


                   {


                       while (true)


                       {


                           Console.WriteLine("************请输入数据**************");


                           string testTask = Console.ReadLine();


                           service.ListLeftPush("test", testTask);


                       }


                   });


                   act.EndInvoke(act.BeginInvoke(null, null));


               }


           }




复制代码