C# Nuget程序集StackExchange.Redis操作Redis 及 Redis 视频资源 及 相关入门指令 牛逼不,全都有

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

首先说下,我的 Redis 系列博客如下:

[置顶] 高并发时,使用Redis应注意的问题【缓存穿透、缓存击穿.、缓存雪崩】

windows环境下配置Redis主从复制-一主二仆,薪火相传、反客为主、哨兵模式

Redis 持久化技术 ,大名鼎鼎的Rdb和Aof,你会选谁呢?

简单介绍下Redis消息队列,实际生产环境中,大数据高并发时,不建议使用Redis做消息队列中间件

Redis 事务,和传统的关系型数据库ACID并不同,别搞混了

Redis常用配置redis.conf介绍,别把默认配置部署到到服务器,否则,会被领导骂的

C# Nuget程序集StackExchange.Redis操作Redis 及 Redis 视频资源 及 相关入门指令 牛逼不,全都有

Redis 的基础数据类型

Window环境下安装Redis 并 自启动Redis 及 Redis Desktop Manager

进入正文

开始之前,我们先进行一个视频教程的宣传,还不错哦。

双十一秒杀系统后端Redis高并发架构实战
链接:https://pan.baidu.com/s/1KGR42Srq6bHmW0Qf0HTlsQ 
提取码:fgdh


亿级流量新浪微博与微信Redis架构实战
链接:https://pan.baidu.com/s/1hsUDpvlif1Q9rdNJjHsrYg 
提取码:03kk

 

培训课程视频:https://www.bilibili.com/video/BV1Bb411p7oK?p=4

培训课程适合初学者。

OK,进入正题

在本篇开始之前,再来一个小插曲,这个小插曲是关于Redis命令的,关于更详细的Redis命令,大家可参考Redis中文网。

1、window命令下连接redis【cmd打开命令黑框】

C:\Users\chenwolong>redis-cli
127.0.0.1:6379> ping
PONG

2、如何设置redis密码

127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass 123456
OK
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379>

上面指令的意思是:获取当前redis密码,设置redis密码为:123456,在此连接redis,结果redis返回给我们:NOAUTH Authentication required.未授权。

因此,设置密码后,我们就需要输入密码进行登录了。

127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

上述为输入密码,并登录。

然后我们就可以使用redis中文网的命令了,例如:Keys *

127.0.0.1:6379> keys *
1) "set01"
2) "rds_set01"
127.0.0.1:6379>

获取Redis的路径,获取Redis持久化dump.Rdb文件所在地址

127.0.0.1:6379> config get dir
1) "dir"
2) "C:\\Program Files\\Redis"
127.0.0.1:6379>

关于redis设置密码这个话题,个人认为非必要,是不需要设置的,因为连接起来比较麻烦,而且违反了redis运行快的理念。

那么,我们再次把密码设置为空,如下:

127.0.0.1:6379> config set requirepass ""
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

演示下清空数据的方法:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379>

注意:flushall 是清空所有数据库的键值对,flushdb 是清空当前数据库的键值对,关于这两个指令,大家慎用,用不好,或误用,就可能被批斗哦,甚至辞退。

最后,我们获取redis配置文件设置的最大连接数

127.0.0.1:6379> CONFIG GET maxclients
1) "maxclients"
2) "10000"
127.0.0.1:6379>

获取当前连接的客户端数量:

connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
127.0.0.1:6379>

如果不进行手动释放,redis 会根据设置的 timeout,清理空闲的链接

OK 

 NetCore 引入Redis

netCore中Redis相关配置如下:

  "RedisOptions": {
    "RedisConnectionString": "127.0.0.1:6379", //Redis 调试环境:127.0.0.1:6379,allowadmin=true   
    "RedisDbNum": 2, //REdis 数据库
    "IotRedisDbNum": 1 //物联网--REdis 数据库
  }

在startup中加载选项模式

            services.Configure<WuAnModels.Document.RedisOptions>(Configuration.GetSection("RedisOptions"));

 

 

 选项类 RedisOptnions

    public class RedisOptions
    {
        public string RedisConnectionString { get; set; }
        public int RedisDbNum { get; set; }
        public int IotRedisDbNum { get; set; }
    }

Redis帮助类

RedisConnectionHelper.cs

/*  
 * ......................我佛慈悲...................... 
 *                       _oo0oo_ 
 *                      o8888888o 
 *                      88" . "88 
 *                      (| -_- |) 
 *                      0\  =  /0 
 *                    ___/`---'\___ 
 *                  .' \\|     |// '. 
 *                 / \\|||  :  |||// \ 
 *                / _||||| -卍-|||||- \ 
 *               |   | \\\  -  /// |   | 
 *               | \_|  ''\---/''  |_/ | 
 *               \  .-\__  '-'  ___/-. / 
 *             ___'. .'  /--.--\  `. .'___ 
 *          ."" '<  `.___\_<|>_/___.' >' "". 
 *         | | :  `- \`.;`\ _ /`;.`/ - ` : | | 
 *         \  \ `_.   \_ __\ /__ _/   .-` /  / 
 *     =====`-.____`.___ \_____/___.-`___.-'===== 
 *                       `=---=' 
 *                        
 *..................佛祖开光 ,永无BUG................... 
 *  
 */
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Configuration;
using WuAnCommon.Document;

namespace RedisHelpers
{
    /// <summary>
    /// ConnectionMultiplexer对象管理帮助类
    /// </summary>
    public static class RedisConnectionHelper
    {
        //系统自定义Key前缀
        public static readonly string SysCustomKey =  ""; 
        

        private static readonly object Locker = new object();
        private static ConnectionMultiplexer _instance;
        private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>(); 
         
        /// <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];
        }

        private static ConnectionMultiplexer GetManager(string connectionString  =null)
        { 
            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)
        {
            Console.WriteLine("Configuration changed: " + e.EndPoint);
        }

        /// <summary>
        /// 发生错误时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
        {
            Console.WriteLine("ErrorMessage: " + e.Message);
        }

        /// <summary>
        /// 重新建立连接之前的错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
        {
            Console.WriteLine("ConnectionRestored: " + e.EndPoint);
        }

        /// <summary>
        /// 连接失败 , 如果重新连接成功你将不会收到这个通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            Console.WriteLine("重新连接: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)
        {
            Console.WriteLine("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)
        {
            Console.WriteLine("InternalError:Message" + e.Exception.Message);
        }

        #endregion 事件
    }
}
View Code

RedisHelper.cs

/*  
 * ......................我佛慈悲...................... 
 *                       _oo0oo_ 
 *                      o8888888o 
 *                      88" . "88 
 *                      (| -_- |) 
 *                      0\  =  /0 
 *                    ___/`---'\___ 
 *                  .' \\|     |// '. 
 *                 / \\|||  :  |||// \ 
 *                / _||||| -卍-|||||- \ 
 *               |   | \\\  -  /// |   | 
 *               | \_|  ''\---/''  |_/ | 
 *               \  .-\__  '-'  ___/-. / 
 *             ___'. .'  /--.--\  `. .'___ 
 *          ."" '<  `.___\_<|>_/___.' >' "". 
 *         | | :  `- \`.;`\ _ /`;.`/ - ` : | | 
 *         \  \ `_.   \_ __\ /__ _/   .-` /  / 
 *     =====`-.____`.___ \_____/___.-`___.-'===== 
 *                       `=---=' 
 *                        
 *..................佛祖开光 ,永无BUG................... 
 *  
 */
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RedisHelpers
{
    /// <summary>
    /// Redis操作 Redis 命令参考:http://doc.redisfans.com/index.html
    /// </summary>
    /// 
    /// <summary>
    /// 该项目源码参考博客:https://www.cnblogs.com/cang12138/p/8884362.html
    /// </summary>
    /// 
    /// <summary>
    /// 2021年3月15日,进行扩展,扩展者主页:https://www.cnblogs.com/chenwolong/
    /// </summary>
    ///  
    /// <summary>
    /// 视频基础教程:https://www.bilibili.com/video/BV1Bb411p7oK?p=4
    /// </summary>
    public class RedisHelper
    {
        private int DbNum { get; set; }
        /// <summary>
        /// Redis连接
        /// </summary>
        private readonly ConnectionMultiplexer _conn;

        /// <summary>
        /// 设置自定义键
        /// </summary>
        public string CustomKey;

        #region 构造函数

        public RedisHelper(int dbNum = 0)
            : this(dbNum, null)
        {
        }

        public RedisHelper(int dbNum, string readWriteHosts)
        {
            DbNum = dbNum;
            _conn = string.IsNullOrWhiteSpace(readWriteHosts) ?
                    RedisConnectionHelper.Instance :
                    RedisConnectionHelper.GetConnectionMultiplexer(readWriteHosts);
        }

        #endregion 构造函数

        #region String

        #region 同步方法

        /// <summary>
        /// 保存单个key value
        /// </summary>
        /// <param name="key">Redis Key</param>
        /// <param name="value">保存的值</param>
        /// <param name="expiry">过期时间</param>
        /// <returns></returns>
        public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?))
        {
            key = AddSysCustomKey(key);
            return Do(db => db.StringSet(key, value, expiry));
        }

        /// <summary>
        /// 保存多个key value
        /// </summary>
        /// <param name="keyValues">键值对</param>
        /// <returns></returns>
        public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> keyValues)
        {
            List<KeyValuePair<RedisKey, RedisValue>> newkeyValues = keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();
            return Do(db => db.StringSet(newkeyValues.ToArray()));
        }

        /// <summary>
        /// 保存一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public bool StringSet<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
        {
            key = AddSysCustomKey(key);
            string json = ConvertJson(obj);
            return Do(db => db.StringSet(key, json, expiry));
        }

        /// <summary>
        /// 获取单个key的值
        /// </summary>
        /// <param name="key">Redis Key</param>
        /// <returns></returns>
        public string StringGet(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db => db.StringGet(key));
        }

        /// <summary>
        /// 获取多个Key
        /// </summary>
        /// <param name="listKey">Redis Key集合</param>
        /// <returns></returns>
        public RedisValue[] StringGet(List<string> listKey)
        {
            List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();
            return Do(db => db.StringGet(ConvertRedisKeys(newKeys)));
        }

        /// <summary>
        /// 获取一个key的对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T StringGet<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db => ConvertObj<T>(db.StringGet(key)));
        }

        /// <summary>
        /// 为数字增长val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val">可以为负</param>
        /// <returns>增长后的值</returns>
        public double StringIncrement(string key, double val = 1)
        {
            key = AddSysCustomKey(key);
            return Do(db => db.StringIncrement(key, val));
        }

        /// <summary>
        /// 为数字减少val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val">可以为负</param>
        /// <returns>减少后的值</returns>
        public double StringDecrement(string key, double val = 1)
        {
            key = AddSysCustomKey(key);
            return Do(db => db.StringDecrement(key, val));
        }

        #endregion 同步方法

        #region 异步方法

        /// <summary>
        /// 保存单个key value
        /// </summary>
        /// <param name="key">Redis Key</param>
        /// <param name="value">保存的值</param>
        /// <param name="expiry">过期时间</param>
        /// <returns></returns>
        public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?))
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.StringSetAsync(key, value, expiry));
        }

        /// <summary>
        /// 保存多个key value
        /// </summary>
        /// <param name="keyValues">键值对</param>
        /// <returns></returns>
        public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> keyValues)
        {
            List<KeyValuePair<RedisKey, RedisValue>> newkeyValues =
                keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();
            return await Do(db => db.StringSetAsync(newkeyValues.ToArray()));
        }

        /// <summary>
        /// 保存一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
        {
            key = AddSysCustomKey(key);
            string json = ConvertJson(obj);
            return await Do(db => db.StringSetAsync(key, json, expiry));
        }

        /// <summary>
        /// 获取单个key的值
        /// </summary>
        /// <param name="key">Redis Key</param>
        /// <returns></returns>
        public async Task<string> StringGetAsync(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.StringGetAsync(key));
        }

        /// <summary>
        /// 获取多个Key
        /// </summary>
        /// <param name="listKey">Redis Key集合</param>
        /// <returns></returns>
        public async Task<RedisValue[]> StringGetAsync(List<string> listKey)
        {
            List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();
            return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys)));
        }

        /// <summary>
        /// 获取一个key的对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<T> StringGetAsync<T>(string key)
        {
            key = AddSysCustomKey(key);
            string result = await Do(db => db.StringGetAsync(key));
            return ConvertObj<T>(result);
        }

        /// <summary>
        /// 为数字增长val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val">可以为负</param>
        /// <returns>增长后的值</returns>
        public async Task<double> StringIncrementAsync(string key, double val = 1)
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.StringIncrementAsync(key, val));
        }

        /// <summary>
        /// 为数字减少val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val">可以为负</param>
        /// <returns>减少后的值</returns>
        public async Task<double> StringDecrementAsync(string key, double val = 1)
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.StringDecrementAsync(key, val));
        }

        #endregion 异步方法

        #endregion String

        #region Hash

        #region 同步方法

        /// <summary>
        /// 判断某个数据是否已经被缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public bool HashExists(string key, string dataKey)
        {
            key = AddSysCustomKey(key);
            return Do(db => db.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);
            return Do(db =>
            {
                string json = ConvertJson(t);
                return db.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 Do(db => db.HashDelete(key, dataKey));
        }

        /// <summary>
        /// 移除hash中的多个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKeys"></param>
        /// <returns></returns>
        public long HashDelete(string key, List<RedisValue> dataKeys)
        {
            key = AddSysCustomKey(key);
            //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};
            return Do(db => db.HashDelete(key, dataKeys.ToArray()));
        }

        /// <summary>
        /// 从hash表获取某个值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public string HashGet(string key, string dataKey)
        {
            key = AddSysCustomKey(key);
            return Do(db =>
            {
                string value = db.HashGet(key, dataKey);
                return value;
            });
        }

        /// <summary>
        /// 从hash表获取Model
        /// </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);
            return Do(db =>
            {
                string value = db.HashGet(key, dataKey);
                return ConvertObj<T>(value);
            });
        }

        /// <summary>
        /// 从hash表获取List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public IList<T> HashGetList<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db =>
            {
                RedisValue[] values = db.HashValues(key);
                return ConvetList<T>(values);
            });
        }

        /// <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 Do(db => db.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 Do(db => db.HashDecrement(key, dataKey, val));
        }

        /// <summary>
        /// 获取hashkey所有Redis key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<T> HashKeys<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db =>
            {
                RedisValue[] values = db.HashKeys(key);
                return ConvetList<T>(values);
            });
        }

        #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 Do(db => db.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);
            return await Do(db =>
            {
                string json = ConvertJson(t);
                return db.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 Do(db => db.HashDeleteAsync(key, dataKey));
        }

        /// <summary>
        /// 移除hash中的多个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKeys"></param>
        /// <returns></returns>
        public async Task<long> HashDeleteAsync(string key, List<RedisValue> dataKeys)
        {
            key = AddSysCustomKey(key);
            //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};
            return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray()));
        }

        /// <summary>
        /// 从hash表获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public async Task<T> HashGeAsync<T>(string key, string dataKey)
        {
            key = AddSysCustomKey(key);
            string value = await Do(db => db.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 Do(db => db.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 Do(db => db.HashDecrementAsync(key, dataKey, val));
        }

        /// <summary>
        /// 获取hashkey所有Redis key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<List<T>> HashKeysAsync<T>(string key)
        {
            key = AddSysCustomKey(key);
            RedisValue[] values = await Do(db => db.HashKeysAsync(key));
            return ConvetList<T>(values);
        }

        #endregion 异步方法

        #endregion Hash

        #region List

        #region 同步方法

        /// <summary>
        /// 移除指定ListId的内部List的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void ListRemove<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            Do(db => db.ListRemove(key, ConvertJson(value)));
        }

        /// <summary>
        /// 获取指定key的List
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<T> ListRange<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis =>
            {
                var values = redis.ListRange(key);
                return ConvetList<T>(values);
            });
        }

        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void ListRightPush<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            Do(db => db.ListRightPush(key, ConvertJson(value)));
        }

        /// <summary>
        /// 出队
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T ListRightPop<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db =>
             {
                 var value = db.ListRightPop(key);
                 return ConvertObj<T>(value);
             });
        }

        /// <summary>
        /// 入栈
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void ListLeftPush<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            Do(db => db.ListLeftPush(key, ConvertJson(value)));
        }

        /// <summary>
        /// 出栈
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T ListLeftPop<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db =>
            {
                var value = db.ListLeftPop(key);
                return ConvertObj<T>(value);
            });
        }

        /// <summary>
        /// 获取集合中的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long ListLength(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.ListLength(key));
        }

        #endregion 同步方法

        #region 异步方法

        /// <summary>
        /// 移除指定ListId的内部List的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public async Task<long> ListRemoveAsync<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.ListRemoveAsync(key, ConvertJson(value)));
        }

        /// <summary>
        /// 获取指定key的List
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<List<T>> ListRangeAsync<T>(string key)
        {
            key = AddSysCustomKey(key);
            var values = await Do(redis => redis.ListRangeAsync(key));
            return ConvetList<T>(values);
        }

        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public async Task<long> ListRightPushAsync<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.ListRightPushAsync(key, ConvertJson(value)));
        }

        /// <summary>
        /// 出队
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<T> ListRightPopAsync<T>(string key)
        {
            key = AddSysCustomKey(key);
            var value = await Do(db => db.ListRightPopAsync(key));
            return ConvertObj<T>(value);
        }

        /// <summary>
        /// 入栈
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public async Task<long> ListLeftPushAsync<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value)));
        }

        /// <summary>
        /// 出栈
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<T> ListLeftPopAsync<T>(string key)
        {
            key = AddSysCustomKey(key);
            var value = await Do(db => db.ListLeftPopAsync(key));
            return ConvertObj<T>(value);
        }

        /// <summary>
        /// 获取集合中的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> ListLengthAsync(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.ListLengthAsync(key));
        }

        #endregion 异步方法

        #endregion List

        #region SortedSet 有序集合

        #region 同步方法

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="score"></param>
        public bool SortedSetAdd<T>(string key, T value, double score)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SortedSetAdd(key, ConvertJson<T>(value), score));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public bool SortedSetRemove<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SortedSetRemove(key, ConvertJson(value)));
        }

        /// <summary>
        /// 获取全部
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<T> SortedSetRangeByRank<T>(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis =>
            {
                var values = redis.SortedSetRangeByRank(key);
                return ConvetList<T>(values);
            });
        }

        /// <summary>
        /// 获取集合中的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long SortedSetLength(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SortedSetLength(key));
        }

        #endregion 同步方法

        #region 异步方法

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="score"></param>
        public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson<T>(value), score));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public async Task<bool> SortedSetRemoveAsync<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value)));
        }

        /// <summary>
        /// 获取全部
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key)
        {
            key = AddSysCustomKey(key);
            var values = await Do(redis => redis.SortedSetRangeByRankAsync(key));
            return ConvetList<T>(values);
        }

        /// <summary>
        /// 获取集合中的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> SortedSetLengthAsync(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SortedSetLengthAsync(key));
        }

        #endregion 异步方法

        #endregion SortedSet 有序集合

        #region Set 无序集合,2021年3月15日,扩展人:陈卧龙
        /// <summary>
        /// Set 和 List 的区别在于:Set属于无重复集合,而List链表允许重复
        /// </summary>
        /// <returns></returns>
        /// 

        #region 同步方法
        /// <summary>
        /// 向Set中插入元素
        /// 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetAdd<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetAdd(key, ConvertJson(value)));
        }

        /// <summary>
        /// 获取Set内的所有元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public IEnumerable<RedisValue> SetMembers(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetMembers(key));
        }

        /// <summary>
        /// 获取Set的长度
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long SetLength(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetLength(key));
        }
        /// <summary>
        /// 判断Set中是否包含某个值
        /// </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);
            return Do(redis => redis.SetContains(key, ConvertJson(value)));
        }

        /// <summary>
        /// 两个Set集合取交集 全集 不同
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="operation">SetOperation.Union:取Union集合,SetOperation.Intersect:取交集,SetOperation.Difference:取不同 </param>
        /// <param name="key1"></param>
        /// <param name="key2"></param>
        /// <returns></returns>
        public IEnumerable<RedisValue> SetCombine<T>(SetOperation operation, string key1, string key2)
        {
            key1 = AddSysCustomKey(key1);
            key2 = AddSysCustomKey(key2);
            return Do(redis => redis.SetCombine(operation, key1, key2));
        }

        /// <summary>
        /// 两个Set集合取交集 全集 不同,并将得到的结果存储到新的key中,如果新的key已存在,则重写并覆盖原有的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="operation">SetOperation.Union:取Union集合,SetOperation.Intersect:取交集,SetOperation.Difference:取不同</param>
        /// <param name="destination">新的key值</param>
        /// <param name="key1"></param>
        /// <param name="key2"></param>
        /// <returns></returns>
        public long SetCombineAndStore<T>(SetOperation operation, string destination, string key1, string key2)
        {
            key1 = AddSysCustomKey(key1);
            key2 = AddSysCustomKey(key2);
            destination = AddSysCustomKey(destination);
            return Do(redis => redis.SetCombineAndStore(operation, destination, key1, key2));
        }


        /// <summary>
        /// 将 member 元素从 source 集合移动到 destination 集合。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="destination">新的key值,移除的元素将会保存在destination中</param>
        /// <param name="key">被移除的数据源</param>
        /// <param name="value">被移除的值</param>
        /// <returns></returns>
        public bool SetMove<T>(string destination, string key, T value)
        {
            key = AddSysCustomKey(key);
            destination = AddSysCustomKey(destination);
            return Do(redis => redis.SetMove(key, destination, ConvertJson(value)));
        }


        /// <summary>
        /// 移除Set集合中的一个随机元素并返回剩余集合中的一个随机元素。
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string SetPop(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetPop(key));
        }

        /// <summary>
        /// 返回Set集合中一个随机元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string SetRandomMember(string key)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetRandomMember(key));
        }

        /// <summary>
        /// 返回Set集合中指定个数的随机元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public IEnumerable<RedisValue> SetRandomMembers(string key, long count)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetRandomMembers(key, count));
        }

        /// <summary>
        /// Set集合中移除指定的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetRemove<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return Do(redis => redis.SetRemove(key, ConvertJson(value)));
        }
        #endregion 同步方法

        #region 异步方法
        /// <summary>
        /// 向Set中插入元素
        /// 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetAddAsync<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return await  Do(redis => redis.SetAddAsync(key, ConvertJson(value)));
        }

        /// <summary>
        /// 获取Set内的所有元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<IEnumerable<RedisValue>> SetMembersAsync(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SetMembersAsync(key));
        }

        /// <summary>
        /// 获取Set的长度
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> SetLengthAsnyc(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SetLengthAsync(key));
        }
        /// <summary>
        /// 判断Set中是否包含某个值
        /// </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);
            return await Do(redis => redis.SetContainsAsync(key, ConvertJson(value)));
        }

        /// <summary>
        /// 两个Set集合取交集 全集 不同
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="operation">SetOperation.Union:取Union集合,SetOperation.Intersect:取交集,SetOperation.Difference:取不同 </param>
        /// <param name="key1"></param>
        /// <param name="key2"></param>
        /// <returns></returns>
        public async Task<IEnumerable<RedisValue>> SetCombineAsync<T>(SetOperation operation, string key1, string key2)
        {
            key1 = AddSysCustomKey(key1);
            key2 = AddSysCustomKey(key2);
            return await Do(redis => redis.SetCombineAsync(operation, key1, key2));
        }

        /// <summary>
        /// 两个Set集合取交集 全集 不同,并将得到的结果存储到新的key中,如果新的key已存在,则重写并覆盖原有的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="operation">SetOperation.Union:取Union集合,SetOperation.Intersect:取交集,SetOperation.Difference:取不同</param>
        /// <param name="destination">新的key值</param>
        /// <param name="key1"></param>
        /// <param name="key2"></param>
        /// <returns></returns>
        public async Task<long> SetCombineAndStoreAsync<T>(SetOperation operation, string destination, string key1, string key2)
        {
            key1 = AddSysCustomKey(key1);
            key2 = AddSysCustomKey(key2);
            destination = AddSysCustomKey(destination);
            return await Do(redis => redis.SetCombineAndStoreAsync(operation, destination, key1, key2));
        }


        /// <summary>
        /// 将 member 元素从 source 集合移动到 destination 集合。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="destination">新的key值,移除的元素将会保存在destination中</param>
        /// <param name="key">被移除的数据源</param>
        /// <param name="value">被移除的值</param>
        /// <returns></returns>
        public async Task<bool> SetMoveAsync<T>(string destination, string key, T value)
        {
            key = AddSysCustomKey(key);
            destination = AddSysCustomKey(destination);
            return await Do(redis => redis.SetMoveAsync(key, destination, ConvertJson(value)));
        }


        /// <summary>
        /// 移除Set集合中的一个随机元素并返回剩余集合中的一个随机元素。
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> SetPopAsync(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SetPopAsync(key));
        }

        /// <summary>
        /// 返回Set集合中一个随机元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> SetRandomMemberAsync(string key)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SetRandomMemberAsync(key));
        }

        /// <summary>
        /// 返回Set集合中指定个数的随机元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<IEnumerable<RedisValue>> SetRandomMembersAsync(string key, long count)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SetRandomMembersAsync(key, count));
        }

        /// <summary>
        /// Set集合中移除指定的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetRemoveAsync<T>(string key, T value)
        {
            key = AddSysCustomKey(key);
            return await Do(redis => redis.SetRemoveAsync(key, ConvertJson(value)));
        }
        #endregion 异步方法

        #endregion

        #region key

        /// <summary>
        /// 删除单个key
        /// </summary>
        /// <param name="key">redis key</param>
        /// <returns>是否删除成功</returns>
        public bool KeyDelete(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db => db.KeyDelete(key));
        }

        /// <summary>
        /// 删除多个key
        /// </summary>
        /// <param name="keys">rediskey</param>
        /// <returns>成功删除的个数</returns>
        public long KeyDelete(List<string> keys)
        {
            List<string> newKeys = keys.Select(AddSysCustomKey).ToList();
            return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys)));
        }

        /// <summary>
        /// 判断key是否存储
        /// </summary>
        /// <param name="key">redis key</param>
        /// <returns></returns>
        public bool KeyExists(string key)
        {
            key = AddSysCustomKey(key);
            return Do(db => db.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);
            return Do(db => db.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 Do(db => db.KeyExpire(key, expiry));
        }

        #endregion key

        #region 发布订阅

        /// <summary>
        /// Redis发布订阅  订阅
        /// </summary>
        /// <param name="subChannel"></param>
        /// <param name="handler"></param>
        public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null)
        {
            ISubscriber sub = _conn.GetSubscriber();
            sub.Subscribe(subChannel, (channel, message) =>
            {
                //接收订阅消息,处理逻辑
                if (handler == null)
                {
                    Console.WriteLine(subChannel + " 订阅收到消息:" + message);
                }
                else
                {
                    handler(channel, message);
                }
            });
            //写法二
            sub.Subscribe(subChannel, new Action<RedisChannel, RedisValue>((channel, message) =>
            {
                Console.WriteLine(subChannel + " 订阅收到消息:" + message);
            }));
            //写法三
            sub.Subscribe(subChannel, new Action<RedisChannel, RedisValue>(GetMessage));
        }

        /// <summary>
        /// 获取订阅消息(写法三)
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="message"></param>
        static void GetMessage(RedisChannel channel, RedisValue message)
        {
            Console.WriteLine(channel + " 订阅收到消息:" + message);
        }

        /// <summary>
        /// Redis发布订阅  发布
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="channel"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public long Publish<T>(string channel, T msg)
        {
            ISubscriber sub = _conn.GetSubscriber();
            return sub.Publish(channel, ConvertJson(msg));
        }

        /// <summary>
        /// Redis发布订阅  取消订阅
        /// </summary>
        /// <param name="channel"></param>
        public void Unsubscribe(string channel)
        {
            ISubscriber sub = _conn.GetSubscriber();
            sub.Unsubscribe(channel);
        }

        /// <summary>
        /// Redis发布订阅  取消全部订阅
        /// </summary>
        public void UnsubscribeAll()
        {
            ISubscriber sub = _conn.GetSubscriber();
            sub.UnsubscribeAll();
        }

        #endregion 发布订阅

        #region 其他
        /// <summary>
        /// 获取事物
        /// </summary>
        /// <returns></returns>
        public ITransaction CreateTransaction()
        {
            return GetDatabase().CreateTransaction();
        }

        /// <summary>
        /// 获取批处理(管道模式)
        /// </summary>
        /// <returns></returns>
        public IBatch CreateBatch()
        {
            return GetDatabase().CreateBatch();
        }

        public IDatabase GetDatabase()
        {
            return _conn.GetDatabase(DbNum);
        }

        public IServer GetServer(string hostAndPort)
        {
            return _conn.GetServer(hostAndPort);
        }

        /// <summary>
        /// 设置前缀
        /// </summary>
        /// <param name="customKey">自定义键</param>
        public void SetSysCustomKey(string customKey)
        {
            CustomKey = customKey;
        }

        #endregion 其他

        #region 辅助方法
        /// <summary>
        /// 添加自定义键
        /// </summary>
        /// <param name="oldKey"></param>
        /// <returns></returns>
        private string AddSysCustomKey(string oldKey)
        {
            var prefixKey = CustomKey ?? RedisConnectionHelper.SysCustomKey;
            return prefixKey + oldKey;
        }

        private T Do<T>(Func<IDatabase, T> func)
        {
            var database = _conn.GetDatabase(DbNum);
            return func(database);
        }

        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        private string ConvertJson<T>(T value)
        {
            string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value);
            return result;
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        private T ConvertObj<T>(RedisValue value)
        {
            return JsonConvert.DeserializeObject<T>(value);
        }

        private 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;
        }

        private RedisKey[] ConvertRedisKeys(List<string> redisKeys)
        {
            return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray();
        }

        #endregion 辅助方法
    }
}
View Code

webApi调用Redis

基类

    public class BaseService : IBaseService
    {
        public  WuAnModels.Document.FileOptions  fileOptions;
        public  WuAnModels.Document.RedisOptions  redisOptions;
        public RedisHelpers.RedisHelper redis = null;
        public RedisHelpers.RedisHelper iotredis = null;
        static int seed = 13;
        public ThreadLocal<Random> threadLocal = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
        public BaseService() { }

        public BaseService(IOptions<WuAnModels.Document.RedisOptions> _redisOptions)
        {
            this.redisOptions = _redisOptions.Value;
            redis = new RedisHelpers.RedisHelper(redisOptions.RedisDbNum);
            iotredis = new RedisHelpers.RedisHelper(redisOptions.IotRedisDbNum);
        }

        public BaseService(IOptions<WuAnModels.Document.FileOptions> _fileOptions, IOptions<WuAnModels.Document.RedisOptions> _redisOptions)
        {
            this.fileOptions = _fileOptions.Value;
            this.redisOptions = _redisOptions.Value;
            redis = new RedisHelpers.RedisHelper(redisOptions.RedisDbNum,redisOptions.RedisConnectionString);
            iotredis = new RedisHelpers.RedisHelper(redisOptions.IotRedisDbNum, redisOptions.RedisConnectionString);
        }

        public virtual string NewUid()
        {
            return Guid.NewGuid().ToString("N");
        }

        public virtual string GetNumber(int Length)
        {
            if (Length > 10)
            {
                return ""; //int.MaxValue 2147483647
            }
            var Id = threadLocal.Value.Next(100000, int.MaxValue);

            return Id.ToString().Substring(0, Length);
        }
    }





    /// <summary>
    /// 接口 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IBaseService 
    {
        string NewUid();
        string GetNumber(int Length);
    }

实现类

    /// <summary>
    /// 业务逻辑层访问类
    /// </summary>
    public class StudentService: BaseService ,IStudentService 
    {
        private readonly IStudentRepository service;
        public StudentService(IStudentRepository _service, IOptions<WuAnModels.Document.FileOptions> _fileOptions, IOptions<WuAnModels.Document.RedisOptions> _redisOptions):base( _fileOptions,_redisOptions)
        {
            this.service = _service;
        }  
        /// <summary>
        /// 选项模式 读取配置文件
        /// </summary>
        /// <returns></returns>
        public RedisOptions GetRedisOptions()
        {
            return redisOptions;
        }

        /// <summary>
        /// 选项模式 读取配置文件
        /// </summary>
        /// <returns></returns>
        public string Test()
        { 
            redis.StringSet("test", "this is a redis key value");
            return redis.StringGet("test");
        }
    }



 
   ///接口
    public interface IStudentService :IBaseService
    {
        string Test(); 
        RedisOptions GetRedisOptions();

    }

over

2023-04-03更新如下:

模糊查询匹配:

#region 模糊查询 
        /// <summary>
        /// 模糊查询所有匹配的Key值
        /// </summary>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public string[] GetRdsKeysByLua(string pattern)
        {
            var redisResult = Do(db => db.ScriptEvaluate(LuaScript.Prepare("local res = redis.call('KEYS', @keypattern) return res"), new { @keypattern = pattern }));
            string[] preSult = (string[])redisResult;//将返回的结果集转为数组

            return preSult;
        }

        /// <summary>
        /// 查询所有值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public List<T> GetRdsValuesByLua<T>(string pattern)
        {
            var redisResult = Do(db => db.ScriptEvaluate(LuaScript.Prepare("local res = redis.call('KEYS', @keypattern) return res"), new { @keypattern = pattern }));
            string[] preSult = (string[])redisResult;//将返回的结果集转为数组
            List<T> result = new List<T>();
            foreach (var item in preSult)
            {
                result.Add(StringGet<T>(item));
            }
            return result;
        }

        #endregion

 

@天才卧龙的博客

 

posted @ 2021-03-15 17:30  天才卧龙  阅读(471)  评论(0编辑  收藏  举报