• 用redis来实现Session保存的一个简单Demo


    现在很多项目都用Redis(RedisSessionStateProvider)来保存Session数据,但是最近遇到一个比较典型的情况,需要把用户数据全部load到redis里面,在加上RedisSessionStateProvider本身的数据,造成很多内存的浪费。首先我们要知道Session会针对用户的数据,比如用户在chrome登录会保存一套信息,用ie登录有保存一套信息,用FF登录还是保存一套信息,那么redis就保存了3套一样的session data数据

    如RedisSessionStateProvider默认会生成*****_Data来保存我们的session数据,******_Internal来记录session过期,这里的*****_2qfxy3ie51m5oneffzr0jkrd****和****_isudg4h01axx3lnd3pao4zcj****其实是用一个用户在2个浏览器上的数据,我们是否可以只保留一份****——Data数据,多分_Internal数据(用与表示到***_Data数据的关联)

    demo如下:

      public class BaseController : Controller
        {
            string cookieName;
            public BaseController()
            {
                cookieName = SessionStateManage.CookieName;
                
                HttpCookie cookie = System.Web.HttpContext.Current.Request.Cookies[cookieName];
                if (cookie != null)
                {
                    SessionCookieValue = cookie.Value;
                    if (string.IsNullOrEmpty(SessionCookieValue))
                    {
                        UserSession = SessionStateManage.GetUser(SessionCookieValue);
                    }
                }
    
            }
    
            public void Login(UserInfo info)
            {
                string sessionID = Guid.NewGuid().ToString();
                System.Web.HttpContext.Current.Response.Cookies.Set(new HttpCookie(cookieName, sessionID));
                SessionStateManage.SetLogin(sessionID, info);
            }
            public string SessionCookieValue { set; get; }
    
            public UserInfo UserSession { set; get; }
        }
     public class HomeController : BaseController
        {
            public ActionResult Index()
            {         
                if (UserSession == null)
                {
                    UserSession = new UserInfo { Email = "gavin@test", Password = "123", UserID = "1", UserName = "gavin" };
                    Login(UserSession);
                }
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }

    从当前请求中获取cookie,如果有就加载用户信息,如果没有我们在用户登录的时候除了写Redis还需要给浏览器写上cookie

      public class UserInfo
        {
            public string UserID { set; get; }
            public string UserName { set; get; }
            public string Password { set; get; }
            public string Email { set; get; }
        }
        public class SessionStateManage
        {
            static RedisHelper Redis;
            static SessionStateManage()
            {
                CookieName = ConfigurationManager.AppSettings["cookieName"] ?? "SESSION_ID";
                ApplicationName = ConfigurationManager.AppSettings["ApplicationName"] ?? "SESSION";
    
                Redis = new RedisHelper(1);
    
                Redis.SetSysCustomKey(ApplicationName);
                string sessionTimeOutStr = ConfigurationManager.AppSettings["SessionTimeOut"] ?? "20";
                SessionTimeOut = int.Parse(sessionTimeOutStr);
            }
            #region Property
    
            public static string CookieName { get; private set; }
    
            public static string ApplicationName { get; private set; }
    
    
            public static int SessionTimeOut { get; private set; }
            #endregion
    
            public static void SetLogin(string cookieName, UserInfo user)
            {
                Redis.StringSet(cookieName, user.UserID);
                Redis.KeyExpire(cookieName, new TimeSpan(0, SessionTimeOut, 0));
    
                Redis.HashSet(user.UserID, user);
            }
    
            public static UserInfo GetUser(string cookinNme)
            {
                string userID = Redis.StringGet(cookinNme);
                return userID == null ? null : Redis.HashGet<UserInfo>(userID);
            }
    
        }

    用户的session过期直接用redis里面key的过期时间。redis操作需要辅助类如下:

    /// <summary>
        /// ConnectionMultiplexer对象管理帮助类
        /// </summary>
        public static class RedisConnectionHelp
        {
            //系统自定义Key前缀
            public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? "";
    
            //"127.0.0.1:6379,allowadmin=true
            private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString;
    
            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)
            {
                connectionString = connectionString ?? RedisConnectionString;
                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
      /// <summary>
        /// Redis操作
        /// </summary>
        public class RedisHelper
        {
            private int DbNum { get; }
            private readonly ConnectionMultiplexer _conn;
            public string CustomKey;
    
            #region 构造函数
    
            public RedisHelper(int dbNum = 0)
                    : this(dbNum, null)
            {
            }
    
            public RedisHelper(int dbNum, string readWriteHosts)
            {
                DbNum = dbNum;
                _conn =
                    string.IsNullOrWhiteSpace(readWriteHosts) ?
                    RedisConnectionHelp.Instance :
                    RedisConnectionHelp.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);
                });
            }
    
            public bool HashSet<T>(string key, T t)
            {
                key = AddSysCustomKey(key);
                return Do(db =>
                {
                    var val = ToHash<T>(t);
                    db.HashSet(key, val);
                    return true;
                });
            }
            /// <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 T HashGet<T>(string key, string dataKey)
            {
                key = AddSysCustomKey(key);
                return Do(db =>
                {
                    string value = db.HashGet(key, dataKey);
                    return ConvertObj<T>(value);
                });
            }
    
            public T HashGet<T>(string key)
            {
                key = AddSysCustomKey(key);
                return Do(db =>
                {
                    var value = db.HashGetAll(key);
                    return ToEntity<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 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 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);
                    }
                });
            }
    
            /// <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 其他
    
            public ITransaction CreateTransaction()
            {
                return GetDatabase().CreateTransaction();
            }
    
            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 辅助方法
    
            private string AddSysCustomKey(string oldKey)
            {
                var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey;
                return prefixKey + oldKey;
            }
    
            private T Do<T>(Func<IDatabase, T> func)
            {
                var database = _conn.GetDatabase(DbNum);
                return func(database);
            }
    
            private string ConvertJson<T>(T value)
            {
                string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value);
                return result;
            }
    
            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();
            }
            static HashEntry[] ToHash<T>(T obj, bool isIncludNull = false)
            {
                PropertyInfo[] properties = obj.GetType().GetProperties();
    
                return isIncludNull
                    ? properties.Select(x =>
                    {
                        var tempValue = x.GetValue(obj);
                        return new HashEntry(x.Name, tempValue == null ? string.Empty : tempValue.ToString());
                    }).ToArray()
                    : properties.Where(x => x.GetValue(obj) != null).Select(x => new HashEntry(x.Name, x.GetValue(obj).ToString())).ToArray();
            }
    
            static T ToEntity<T>(HashEntry[] hashEntries)
            {
                Type t = typeof(T);
                PropertyInfo[] properties = t.GetProperties();
                var obj = Activator.CreateInstance(typeof(T));
                foreach (var property in properties)
                {
                    HashEntry entry = hashEntries.FirstOrDefault(g => g.Name.ToString().Equals(property.Name));
                    if (entry.Equals(new HashEntry())) continue;
    
                    object value = null;
                    if (!property.PropertyType.IsGenericType)
                    {
                        value = Convert.ChangeType(entry.Value.ToString(), property.PropertyType);
                    }
                    else
                    {
                        Type genericTypeDefinition = property.PropertyType.GetGenericTypeDefinition();
                        if (genericTypeDefinition == typeof(Nullable<>))
                        {
                            if (entry.Value.HasValue)
                            {
                                value = Convert.ChangeType(entry.Value.ToString(), Nullable.GetUnderlyingType(property.PropertyType));
                            }
                        }
                    }
    
                    property.SetValue(obj, value);
                }
                return (T)obj;
            }
    
            #endregion 辅助方法
        }
    View Code

    增加的配置文件

     <connectionStrings> 
        <add name="RedisExchangeHosts" connectionString="127.0.0.1:6379,abortConnect=false,connectRetry=3,connectTimeout=3000,defaultDatabase=0,syncTimeout=3000,version=3.2.1,responseTimeout=3000" />
      </connectionStrings>
      <appSettings>
    
        <add key="cookieName" value="gavintest" />
        <add key="ApplicationName" value="CustStateDemo" />
        <add key="SessionTimeOut" value="20" />
      </appSettings>
    View Code

    运行效果:

    CustStateDemo1是我真正的数据,CustStateDemo451c3163-7586-494d-b331-89bae1045ba0和其他2个一样 数据都是指向CustStateDemo1的数据

  • 相关阅读:
    MySQL:逻辑库与表管理
    MySQL:初识数据库
    MySQL:安装与配置
    C语言之指针
    C语言之二维数组
    C语言之冒泡排序
    C语言之数组
    C语言之函数的声明
    C语言之带有返回值的函数
    C语言之全局变量和局部变量
  • 原文地址:https://www.cnblogs.com/majiang/p/6496484.html
Copyright © 2020-2023  润新知