C# 项目中使用 ServiceStack.Redis 操作 Redis
Redis 官网上可以找到很多针对 C# 的类库支持,这里我们选择了 ServiceStack.Redis 这个客户端,但是 ServiceStack.Redis 有个连接数限制,需要修改源码,另外一个用的比较多的是 StackExchange.Redis,这里不做介绍。
RedisConfiguration 类:
/// <summary> /// 表示配置文件中的 Redis 配置节。 /// </summary> public sealed class RedisConfiguration : ConfigurationSection { /// <summary> /// 检索当前应用程序默认配置的 Redis 配置节。 /// </summary> /// <returns>指定的 Redis 配置节对象,或者,如果该节不存在,则为 null。</returns> public static RedisConfiguration GetConfig() { RedisConfiguration section = (RedisConfiguration)ConfigurationManager.GetSection("RedisConfig"); return section; } /// <summary> /// 检索当前应用程序默认配置的 Redis 配置节。 /// </summary> /// <param name="sectionName">配置节的路径和名称。</param> /// <returns>指定的 Redis 配置节对象,或者,如果该节不存在,则为 null。</returns> public static RedisConfiguration GetConfig(string sectionName) { RedisConfiguration section = (RedisConfiguration)ConfigurationManager.GetSection("RedisConfig"); if (section == null) throw new ConfigurationErrorsException("Section " + sectionName + " is not found."); return section; } /// <summary> /// 获取或设置用于写入的 Redis 服务器地址。 /// </summary> [ConfigurationProperty("WriteServerList", IsRequired = false)] public string WriteServerHosts { get { return (string)base["WriteServerList"]; } set { base["WriteServerList"] = value; } } /// <summary> /// 获取或设置用于读取的 Redis 服务器的主机地址。 /// </summary> [ConfigurationProperty("ReadServerList", IsRequired = false)] public string ReadServerHosts { get { return (string)base["ReadServerList"]; } set { base["ReadServerList"] = value; } } /// <summary> /// 获取或设置 Redis Sentinel 服务器的主机地址。 /// </summary> [ConfigurationProperty("SentinelServerList", IsRequired = false)] public string SentinelServerHosts { get { return (string)base["SentinelServerList"]; } set { base["SentinelServerList"] = value; } } /// <summary> /// 获取或设置 Redis Sentinel 服务器的密码。 /// </summary> [ConfigurationProperty("SentinelPassword", IsRequired = false)] public string SentinelPassword { get { return (string)base["SentinelPassword"]; } set { base["SentinelPassword"] = value; } } /// <summary> /// 获取或设置 Redis 主服务器的名称。 /// </summary> [ConfigurationProperty("MasterName", IsRequired = false)] public string MasterName { get { string masterName = (string)base["MasterName"]; return String.IsNullOrEmpty(masterName) ? "master" : masterName; } set { base["MasterName"] = value; } } /// <summary> /// 获取或设置 Sentinel 的默认数据库。 /// </summary> [ConfigurationProperty("SentinelDb", IsRequired = false, DefaultValue = 0)] public int SentinelDb { get { int sentinelDb = (int)base["SentinelDb"]; return sentinelDb >= 0 ? sentinelDb : 0; } set { base["SentinelDb"] = value; } } /// <summary> /// 最大写入连接池大小。 /// </summary> [ConfigurationProperty("MaxWritePoolSize", IsRequired = false, DefaultValue = 5)] public int MaxWritePoolSize { get { int maxWritePoolSize = (int)base["MaxWritePoolSize"]; return maxWritePoolSize > 0 ? maxWritePoolSize : 5; } set { base["MaxWritePoolSize"] = value; } } /// <summary> /// 最大读取连接池大小。 /// </summary> [ConfigurationProperty("MaxReadPoolSize", IsRequired = false, DefaultValue = 5)] public int MaxReadPoolSize { get { int maxReadPoolSize = (int)base["MaxReadPoolSize"]; return maxReadPoolSize > 0 ? maxReadPoolSize : 5; } set { base["MaxReadPoolSize"] = value; } } /// <summary> /// 自动重启。 /// </summary> [ConfigurationProperty("AutoStart", IsRequired = false, DefaultValue = true)] public bool AutoStart { get { return (bool)base["AutoStart"]; } set { base["AutoStart"] = value; } } /// <summary> /// 本地缓存到期时间,单位:秒。 /// </summary> [ConfigurationProperty("CacheExpires", IsRequired = false, DefaultValue = 36000)] public int CacheExpires { get { return (int)base["CacheExpires"]; } set { base["CacheExpires"] = value; } } /// <summary> /// 是否记录日志,该设置仅用于排查 Redis 运行时出现的问题,如 Redis 工作正常,请关闭该项。 /// </summary> [ConfigurationProperty("RecordeLog", IsRequired = false, DefaultValue = false)] public bool RecordeLog { get { return (bool)base["RecordeLog"]; } set { base["RecordeLog"] = value; } } }
RedisKeys 类定义全局 Key:
/// <summary> /// 全局 Key 定义。 /// </summary> public static class RedisKeys { #region 广告相关... /// <summary> /// 指定城市唯一编号指定唯一广告编号的信息实体对象,{0}:指定城市唯一编号,{1}:指定广告编码。 /// </summary> public static readonly string ADVERTISEMENTSEAT_CITY_BAIDUADID = "AdvertisementSeat_City_{0}_BaiDuAdId_{1}"; /// <summary> /// 指定城市唯一编号指定广告投放目标的信息实体对象,{0}:指定城市唯一编号,{1}:指定广告投放目标。 /// </summary> public static readonly string ADVERTISEMENTSEAT_CITY_BAIDUADID_TARGET = "AdvertisementSeat_City_{0}_Target_{1}"; /// <summary> /// 指定城市唯一编号指定唯一广告编号的信息实体对象,{0}:指定城市唯一编号,{1}:指定产品类型编码。 /// </summary> public static readonly string ADVERTISEMENTSEAT_CITY_CONDITION = "AdvertisementSeat_City_{0}_Condition_{1}"; #endregion }
RedisConnectType 类定义 Redis 建立连接的方式,连接池模式,及时连接及时释放模式:
/// <summary> /// 定义 Redis 建立连接的方式,连接池模式,及时连接及时释放模式。 /// </summary> public enum RedisConnectType { /// <summary> /// 连接池链接方式。 /// </summary> PooledRedisClient, /// <summary> /// 短连接方式,用完就释放的模式。 /// </summary> ShortConnectClient }
RedisExpires 中统一定义了 Redis 数据的有效时间:
/// <summary> /// Redis 有效时间(单位:分钟)定义类。 /// </summary> public static class RedisExpires { /// <summary> /// 1 分钟。 /// </summary> public static readonly int ONE_MINUTE = 1; /// <summary> /// 10 分钟。 /// </summary> public static readonly int TEN_MINUTE = 10; /// <summary> /// 半小时。 /// </summary> public static readonly int HALF_HOUR = 30; /// <summary> /// 1 小时。 /// </summary> public static readonly int ONE_HOUR = 60; /// <summary> /// 半天。 /// </summary> public static readonly int HALF_DAY = 60 * 12; /// <summary> /// 1 天。 /// </summary> public static readonly int ONE_DAY = 60 * 24; /// <summary> /// 1 周。 /// </summary> public static readonly int ONE_WEEK = 7 * 60 * 24; /// <summary> /// 1 个月。 /// </summary> public static readonly int ONE_MONTH = 30 * 60 * 24; }
RedisManager 类中提供了常用的操作:
/// <summary> /// 提供一组用于 Redis 连接池管理对象的工具和方法。 /// </summary> public sealed class RedisManager { /// <summary> /// 声明 Redis 配置信息。 /// </summary> private static RedisConfiguration _redisConfiguration = RedisConfiguration.GetConfig(); /// <summary> /// 声明 Redis 客户端连接的线程安全池对象。 /// </summary> private static IRedisClientsManager _redisClientsManager = null; ///// <summary> ///// 建立 Redis 连接的方式(默认是连接池的方式)。 ///// </summary> //private RedisConnectType ConnnectType = RedisConnectType.PooledRedisClient; ///// <summary> ///// ip ///// </summary> //private string RedisServerIP = ""; ///// <summary> ///// 端口 ///// </summary> //private int RedisServerPort = 6379; ///// <summary> ///// 数据库编号 ///// </summary> //private int RedisServerDb = 0; /// <summary> /// 声明 _lockObject 对象。 /// </summary> private object _lockObject = new object(); /// <summary> /// 初始化 Redis 连接池管理对象。 /// </summary> static RedisManager() { CreateManager(); } /// <summary> /// 创建 Redis 连接池管理对象。 /// </summary> private static void CreateManager() { string[] sentinelServerHosts = SplitServerHosts(_RedisConfiguration.SentinelServerHosts, ","); var redisSentinel = new RedisSentinel(sentinelServerHosts, _RedisConfiguration.MasterName); _redisClientsManager = redisSentinel.Start(); } /// <summary> /// 取得服务器主机地址集合。 /// </summary> /// <param name="serverHosts">服务器主机地址。</param> /// <param name="split">分隔符。</param> /// <returns>服务器主机地址集合。</returns> private static string[] SplitServerHosts(string serverHosts, string split) { return serverHosts.Split(split.ToArray()); } /// <summary> /// 获取 Redis 客户端缓存操作对象。 /// </summary> public static IRedisClient GetClient() { if (_redisClientsManager == null) CreateManager(); var redisClient = _redisClientsManager.GetClient(); redisClient.Password = _RedisConfiguration.SentinelPassword; #if(DEBUG) redisClient.Db = _RedisConfiguration.SentinelDb; #endif return redisClient; } /// <summary> /// 刷新全部数据。 /// </summary> public static void FlushAll() { using (IRedisClient redis = GetClient()) { redis.FlushAll(); } } #region 项... /// <summary> /// 设置指定的项到指定的键中。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>如果设置成功,则为 true;否则为 false。</returns> public static bool ItemSet<T>(string key, T t) { using (IRedisClient redis = GetClient()) { return redis.Set(key, t); } } /// <summary> /// 设置指定的项到指定的键中。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <param name="expire">指定的有效期(单位:分钟)。</param> /// <returns>如果设置成功,则为 true;否则为 false。</returns> public static bool ItemSetExpire<T>(string key, T t, int expire) { using (IRedisClient redis = GetClient()) { return redis.Set(key, t, DateTime.Now.Add(TimeSpan.FromMinutes(expire))); } } /// <summary> /// 获取指定的键的项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns>如果存在该项,则返回该项,否则返回 null。</returns> public static T ItemGet<T>(string key) where T : class { using (IRedisClient redis = GetClient()) { return redis.Get<T>(key); } } /// <summary> /// 移除指定的键的项。 /// </summary> /// <param name="key">指定的键。</param> /// <returns>如果移除成功,则为 true;否则为 false。</returns> public static bool ItemRemove(string key) { using (IRedisClient redis = GetClient()) { return redis.Remove(key); } } #endregion #region 列表... /// <summary> /// 添加项到指定键的列表。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> public static void ListAdd<T>(string key, T t) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); redisTypedClient.AddItemToList(redisTypedClient.Lists[key], t); } } /// <summary> /// 将指定的对象集合的元素添加到指定键的列表末尾。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="tList">指定的项的集合。</param> public static void ListAddRange<T>(string key, List<T> tList) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); redisTypedClient.Lists[key].AddRange(tList); } } /// <summary> /// 从指定键的列表中移除指定的项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>返回一个值,该值表示是否移除成功。</returns> public static bool ListRemove<T>(string key, T t) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); return redisTypedClient.RemoveItemFromList(redisTypedClient.Lists[key], t) > 0; } } /// <summary> /// 从指定键的列表中移除所有的项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> public static void ListRemoveAll<T>(string key) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); redisTypedClient.Lists[key].RemoveAll(); } } /// <summary> /// 获取指定键的列表中实际包含的元素数。 /// </summary> /// <param name="key">指定的键。</param> /// <returns>指定的键中实际包含的元素数。</returns> public static int ListCount(string key) { using (IRedisClient redis = GetClient()) { return (int)redis.GetListCount(key); } } /// <summary> /// 从指定键的列表中获取指定范围的元素。 /// </summary> /// <typeparam name="T">指定项的类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="start">范围开始处的从零开始的索引。</param> /// <param name="count">范围中的元素数。</param> /// <returns>指定键的列表中的范围的元素。</returns> public static List<T> ListGetRange<T>(string key, int index, int count) { using (IRedisClient redis = GetClient()) { var c = redis.As<T>(); return c.Lists[key].GetRange(index, index + count - 1); } } /// <summary> /// 获取指定键的列表中的所有元素。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns>指定键的列表中的范围的元素。</returns> public static List<T> ListGetAll<T>(string key) { using (IRedisClient redis = GetClient()) { var c = redis.As<T>(); return c.Lists[key].GetRange(0, c.Lists[key].Count); } } /// <summary> /// 分页获取指定键的列表中的元素。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="pageIndex">指定的分页索引。</param> /// <param name="pageSize">指定的分页大小。</param> /// <returns>指定键的列表中的范围的元素。</returns> public static List<T> ListGetAll<T>(string key, int pageIndex, int pageSize) { int start = pageSize * (pageIndex - 1); return ListGetRange<T>(key, start, pageSize); } /// <summary> /// 设置指定键的列表的有效期。 /// </summary> /// <param name="key">指定的键。</param> /// <param name="datetime">有效期。</param> public static void ListSetExpire(string key, DateTime datetime) { using (IRedisClient redis = GetClient()) { redis.ExpireEntryAt(key, datetime); } } #endregion #region 集合... /// <summary> /// 将一个或多个元素加入到集合指定的键中,已经存在于集合的元素将被忽略。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> public static void SetAdd<T>(string key, T t) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); redisTypedClient.Sets[key].Add(t); } } /// <summary> /// 获取指定的键的集合中实际包含的元素数。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns>指定的键的集合中实际包含的元素数。</returns> public static int SetCount<T>(string key) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); return redisTypedClient.Sets[key].Count(); } } /// <summary> /// 确定某项是否在指定键的集合中。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>如果存在该项,则为 true;否则为 false。</returns> public static bool SetContains<T>(string key, T t) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); return redisTypedClient.Sets[key].Contains(t); } } /// <summary> /// 从指定键的集合中移除特定对象的第一个匹配项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>如果移除成功,则为 true;否则为 false。</returns> public static bool SetRemove<T>(string key, T t) { using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); return redisTypedClient.Sets[key].Remove(t); } } /// <summary> /// 获取指定键的数据集的所有项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns>指定键的数据集的所有项</returns> public static IList<T> SetGetAll<T>(string key) { List<T> result = new List<T>(); using (IRedisClient redis = GetClient()) { var redisTypedClient = redis.As<T>(); var sets = redisTypedClient.Sets[key]; if (sets != null && sets.Count > 0) { foreach (var item in sets) { result.Add(item); } } } return result; } #endregion #region 哈希表... /// <summary> /// 确定某项是否在指定键的哈希表中。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="dataKey">数据项的键。</param> /// <returns>如果存在该项,则为 true;否则为 false。</returns> public static bool HashSetContains<T>(string key, string dataKey) { using (IRedisClient redis = GetClient()) { return redis.HashContainsEntry(key, dataKey); } } /// <summary> /// 设置指定的项到指定键的哈希表中。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="dataKey">数据项的键。</param> /// <returns>如果设置成功,则为 true;否则为 false。</returns> public static bool HashSetAdd<T>(string key, string dataKey, T t) { using (IRedisClient redis = GetClient()) { string value = JsonSerializer.SerializeToString(t); return redis.SetEntryInHash(key, dataKey, value); } } /// <summary> /// 移除哈希表中指定键的项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="dataKey">数据项的键。</param> /// <returns>如果移除成功,则为 true;否则为 false。</returns> public static bool HashSetRemove(string key, string dataKey) { using (IRedisClient redis = GetClient()) { return redis.RemoveEntryFromHash(key, dataKey); } } /// <summary> /// 移除哈希表中的所有项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="dataKey">数据项的键。</param> /// <returns>如果移除成功,则为 true;否则为 false。</returns> public static bool HashSetRemoveAll(string key) { using (IRedisClient redis = GetClient()) { return redis.Remove(key); } } /// <summary> /// 获取哈希表中的指定键的项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="dataKey">数据项的键。</param> /// <returns>指定键的哈希表的项。</returns> public static T HashSetGet<T>(string key, string dataKey) { using (IRedisClient redis = GetClient()) { string value = redis.GetValueFromHash(key, dataKey); return JsonSerializer.DeserializeFromString<T>(value); } } /// <summary> /// 获取指定键的哈希表的所有项。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns>指定键的哈希表的所有项。</returns> public static List<T> HashSetGetAll<T>(string key) { using (IRedisClient redis = GetClient()) { var list = redis.GetHashValues(key); if (list != null && list.Count > 0) { List<T> result = new List<T>(); foreach (var item in list) { var value = JsonSerializer.DeserializeFromString<T>(item); result.Add(value); } return result; } return null; } } /// <summary> /// 设置指定键的哈希表的有效期。 /// </summary> /// <param name="key">指定的键。</param> /// <param name="expire">指定的有效期时间(单位:分钟)。</param> public static void HashSetExpire(string key, int expire) { using (IRedisClient redis = GetClient()) { redis.ExpireEntryAt(key, DateTime.Now.Add(TimeSpan.FromMinutes(expire))); } } #endregion #region 有序集合... /// <summary> /// 添加指定项到指定键的有序集合。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>如果成功添加,则为 true;否则为 false。</returns> public static bool SortedSetAdd<T>(string key, T t) { using (IRedisClient redis = GetClient()) { string value = JsonSerializer.SerializeToString<T>(t); return redis.AddItemToSortedSet(key, value); } } /// <summary> /// 添加指定项到指定键的有序集合,评分用于排序。如果该元素已经存在,则根据评分更新该元素的顺序。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <param name="score">用于排序的评分值。</param> /// <returns>如果成功添加,则为 true;否则为 false。</returns> public static bool SortedSetAdd<T>(string key, T t, double score) { using (IRedisClient redis = GetClient()) { string value = JsonSerializer.SerializeToString<T>(t); return redis.AddItemToSortedSet(key, value, score); } } /// <summary> /// 从指定键的有序集合中移除指定的元素。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>如果成功移除,则为 true;否则为 false。</returns> public static bool SortedSetRemove<T>(string key, T t) { using (IRedisClient redis = GetClient()) { string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t); return redis.RemoveItemFromSortedSet(key, value); } } /// <summary> /// 从指定键的有序集合尾部移除指定的索引后的匹配项。 /// </summary> /// <param name="key">指定的键。</param> /// <param name="size">保留的条数。</param> /// <returns>移除的元素数量。</returns> public static int SortedSetTrim(string key, int size) { using (IRedisClient redis = GetClient()) { return (int)redis.RemoveRangeFromSortedSet(key, size, 9999999); } } /// <summary> /// 获取指定的键的有序集合中实际包含的元素数。 /// </summary> /// <param name="key">指定的键。</param> /// <returns>指定的键的有序集合中实际包含的元素数。</returns> public static int SortedSetCount(string key) { using (IRedisClient redis = GetClient()) { return (int)redis.GetSortedSetCount(key); } } /// <summary> /// 分页获取指定键的有序集合中的元素。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="pageIndex">指定的分页索引。</param> /// <param name="pageSize">指定的分页大小。</param> /// <returns>指定键的有序集合中的元素集合。</returns> public static List<T> SortedSetGetList<T>(string key, int pageIndex, int pageSize) { using (IRedisClient redis = GetClient()) { var list = redis.GetRangeFromSortedSet(key, (pageIndex - 1) * pageSize, pageIndex * pageSize - 1); if (list != null && list.Count > 0) { List<T> result = new List<T>(); foreach (var item in list) { var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item); result.Add(data); } return result; } } return null; } /// <summary> /// 获取指定键的有序集合中的所有元素。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns>指定键的有序集合中的元素集合。</returns> public static List<T> SortedSetGetListALL<T>(string key) { using (IRedisClient redis = GetClient()) { var list = redis.GetRangeFromSortedSet(key, 0, 9999999); if (list != null && list.Count > 0) { List<T> result = new List<T>(); foreach (var item in list) { var data = JsonSerializer.DeserializeFromString<T>(item); result.Add(data); } return result; } } return null; } /// <summary> /// 设置指定键的有序集合的有效期。 /// </summary> /// <param name="key">指定的键。</param> /// <param name="expire">指定的有效期(单位:分钟)。</param> public static void SortedSetSetExpire(string key, int expire) { using (IRedisClient redis = GetClient()) { redis.ExpireEntryAt(key, DateTime.Now.Add(TimeSpan.FromMinutes(expire))); } } /// <summary> /// 获取指定键的有序集合中的指定元素的评分。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t">指定的项。</param> /// <returns>指定键的有序集合中的指定元素的评分。</returns> public static double SortedSetGetItemScore<T>(string key, T t) { using (IRedisClient redis = GetClient()) { var data = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t); return redis.GetItemScoreInSortedSet(key, data); } } #endregion #region 二进制... /// <summary> /// 设置 BitMap 值,返回 0 或 1 是成功,返回 -1 是失败。 /// </summary> /// <param name="key">指定的键。</param> /// <param name="offset">偏移量。</param> /// <param name="value">值只能是 0 或 1,其它的值会报错</param> /// <returns>返回 0 或 1 是成功,返回 -1 是失败。</returns> public static long BitSet(string key, int offset, int value) { using (IRedisClient redis = GetClient()) { var rc = redis as RedisClient; if (rc != null) { return rc.SetBit(key, offset, value); } return -1; } } /// <summary> /// 获取 BitMap 值,返回 0 或 1 是成功,返回 -1 是失败。 /// </summary> /// <param name="key">指定的键。</param> /// <param name="offset">偏移量。</param> /// <returns>返回 0 或 1 是成功,返回 -1 是失败。</returns> public static long BitGet(string key, int offset) { using (IRedisClient redis = GetClient()) { var rc = redis as RedisClient; if (rc != null) { return rc.GetBit(key, offset); } return -1; } } public bool ByteSet<T>(string key, T t) { bool result = false; if (t != null) { MemoryStream ms = new MemoryStream(); Serialize(t, ms); byte[] data = ms.ToArray(); using (IRedisClient redis = GetClient()) { return redis.Set(key, data); } } return result; } /// <summary> /// 写入一个实体类T,将其转换成二制进存储,并且数据过期时间一到则立刻删除 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <param name="t"></param> /// <param name="Expire"></param> /// <returns></returns> public bool ByteSetExpire<T>(string key, T t, DateTime Expire) { bool flag = false; if (t != null) { MemoryStream ms = new MemoryStream(); Serialize<T>(t, ms); byte[] data = ms.ToArray(); using (IRedisClient redis = GetClient()) { TimeSpan ts = Expire - DateTime.Now; flag = redis.Set(key, data, ts); } } return flag; } /// <summary> /// 获取 key 值为 key 的实体类 T。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="key">指定的键。</param> /// <returns></returns> public T ByteGet<T>(string key) { using (IRedisClient redis = GetClient()) { byte[] data = redis.Get<byte[]>(key); if (data == null || data.Length == 0) { return default(T); } using (MemoryStream ms = new MemoryStream()) { ms.Write(data, 0, data.Length); ms.Position = 0; return Deserialize<T>(ms); } } } #endregion #region 其他方法... /// <summary> /// 获取当前服务器中的所有 Key。 /// </summary> /// <returns>当前服务器中的所有 Key 的集合。</returns> public static List<string> GetAllKeys() { using (IRedisClient redis = GetClient()) { return redis.GetAllKeys(); } } /// <summary> /// 移除指定集合中的所有 Key。 /// </summary> /// <param name="keys">指定的 Key 集合。</param> public static void RemoveAll(IEnumerable<string> keys) { using (IRedisClient redis = GetClient()) { redis.RemoveAll(keys); } } /// <summary> /// 确定指定的键是否在 Redis 数据库中。 /// </summary> /// <param name="key">指定的键。</param> /// <returns>若存在指定的键,则返回 true,否则返回 false。</returns> public static bool ContainsKey(string key) { using (IRedisClient redis = GetClient()) { return redis.ContainsKey(key); } } /// <summary> /// 获取当前数据库服务器中的指定的 Key。 /// </summary> /// <param name="key">指定的键。</param> /// <returns>若移除指定的键成功,则返回 true,否则返回 false。</returns> public static bool Remove(string key) { using (IRedisClient redis = GetClient()) { return redis.Remove(key); } } /// <summary> /// 获取当前 Redis 信息。 /// </summary> /// <returns>当前 Redis 信息。</returns> public Dictionary<string, string> GetInfo() { using (IRedisClient redis = GetClient()) { return redis.Info; } } /// <summary> /// 将指定的对象序列化成二进制对象。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="obj">指定的对象。</param> /// <param name="stream">序列化的二进制对象。</param> private static void Serialize<T>(T obj, Stream stream) { if (stream == null) throw new ArgumentNullException("stream"); var formatter = new BinaryFormatter(); formatter.Serialize(stream, obj); } /// <summary> /// 将指定的二进制对象反序列化成对象。 /// </summary> /// <typeparam name="T">指定的项类型。</typeparam> /// <param name="obj">指定的对象。</param> /// <param name="stream">序列化的二进制对象。</param> /// <returns>反序列化的对象。</returns> public static T Deserialize<T>(Stream stream) { if (stream == null) throw new ArgumentNullException("stream"); var formatter = new BinaryFormatter(); return (T)formatter.Deserialize(stream); } #endregion }