请选择 进入手机版 | 继续访问电脑版

马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的

[复制链接]
查看2218 | 回复0 | 2019-9-12 16:24:58 | 显示全部楼层 |阅读模式

 1.缓存概念

  1.什么是缓存

    这里要讲到的缓存是服务端缓存,简单的说,缓存就是将一些实时性不高,但访问又十分频繁,大概说要很长时间才能取到的数据给存在内存当中,当有请求时直接返回,不消颠末数据库或接口获取。这样就可以减轻数据库的负担。

  2.为什么要用缓存

    总的来说就是为了进步相应速率(用户体验度),淘汰数据库访问频率。

    在一个用户看来,软件利用的体验度才是关键,在对实时性要求不高的情况下,用户肯定会以为打开界面的相应速率快,能包管寻常工作的应用才是好的。因此为了满足这个需求,通过利用缓存,就可以包管满足在正常工作的条件下相应时间尽大概短。

    例如:当客户端向服务器请求某个数据时,服务器先在缓存中找,如果在缓存中,就直接返回,无需查询数据库;如果请求的数据不在缓存中,这时再去数据库中找,找到后返回给客户端,并将这个资源参加缓存中。这样下次请求相同资源时,就不需

    要毗连数据库了。而且如果把缓存放在内存中,由于对内存的操纵要比对数据库操纵快得多,这样请求时间也会缩短。每当数据发生变革的时候(好比,数据有被修改,或被删除的情况下),要同步的更新缓存信息,确保用户不会在缓存取到旧的数据。

    如果没有利用缓存,用户去请求某个数据,当用户量和数据渐渐增长的时候,就会发现每次用户请求的时间越来越长,且数据库无时不刻都在工作。这样用户和数据库都很痛楚,时间一长,就有大概发生下以下事变:

      1.用户常诉苦应用打开速率太慢,页面经常无相应,偶尔还会出现崩溃的情况。

      2.数据库毗连数满大概说数据库相应慢(处理不外来)。

      3.当并发量上来的时候,大概会导致数据库崩溃,使得应用无法正常利用。

 2.选用Redis还是Memcached

  简单说下这两者的区别,两者都是通过key-value的方式举行存储的,Memcached只有简单的字符串格式,而Redis还支持更多的格式(list、 set、sorted set、hash table ),缓存时利用到的数据都是在内存当中,

  不同的在于Redis支持持久化,集群、简单事务、发布/订阅、主从同步等功能,当断电或软件重启时,Memcached中的数据就已经不存在了,而Redis可以通过读取磁盘中的数据再次利用。

  这里进步Windows版的安装包:传送门 可视化工具:因文件太大无法上传到博客园。代码仓库中有,需要的私信哦~

 3.两者在NetCore 中的利用

  Memcached的利用还是相当简单的,首先在 Startup 类中做以下更改,添加缓存参数 赋值给外部类来方便利用  

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMemoryCache memoryCache)
  2. {
  3. //.... 省略部门代码
  4. DemoWeb.MemoryCache = memoryCache;
  5. //.... 省略部门代码
  6. }
复制代码

  1. DemoWeb中的代码:
复制代码
  1. public class DemoWeb
  2. {
  3. //....省略部门代码
  4. /// <summary>
  5. /// MemoryCache
  6. /// </summary>
  7. public static IMemoryCache MemoryCache { get; set; }
  8. /// <summary>
  9. /// 获取当前请求客户端IP
  10. /// </summary>
  11. /// <returns></returns>
  12. public static string GetClientIp()
  13. {
  14. var ip = HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault()?.Split(',')[0].Trim();
  15. if (string.IsNullOrEmpty(ip))
  16. {
  17. ip = HttpContext.Connection.RemoteIpAddress.ToString();
  18. }
  19. return ip;
  20. }
  21. }
复制代码

  然后创建 MemoryCache 来封装些缓存的简单方法

162516blnhchhstnit4otg.gif
162516otqt4it2ok7zntxh.gif
  1. /// <summary>
  2. /// MemoryCache缓存
  3. /// </summary>
  4. public class MemoryCache
  5. {
  6. private static readonly HashSet<string> Keys = new HashSet<string>();
  7. /// <summary>
  8. /// 缓存前缀
  9. /// </summary>
  10. public string Prefix { get; }
  11. /// <summary>
  12. /// 构造函数
  13. /// </summary>
  14. /// <param name="prefix"></param>
  15. public MemoryCache(string prefix)
  16. {
  17. Prefix = prefix + "_";
  18. }
  19. /// <summary>
  20. /// 获取
  21. /// </summary>
  22. /// <typeparam name="T"></typeparam>
  23. /// <param name="key"></param>
  24. /// <returns></returns>
  25. public T Get<T>(string key)
  26. {
  27. return DemoWeb.MemoryCache.Get<T>(Prefix + key);
  28. }
  29. /// <summary>
  30. /// 设置 无逾期时间
  31. /// </summary>
  32. /// <param name="key"></param>
  33. /// <param name="data"></param>
  34. public void Set(string key, object data)
  35. {
  36. key = Prefix + key;
  37. DemoWeb.MemoryCache.Set(key, data);
  38. if (!Keys.Contains(key))
  39. {
  40. Keys.Add(key);
  41. }
  42. }
  43. /// <summary>
  44. /// 设置
  45. /// </summary>
  46. /// <param name="key"></param>
  47. /// <param name="data"></param>
  48. /// <param name="absoluteExpiration"></param>
  49. public void Set(string key, object data, DateTimeOffset absoluteExpiration)
  50. {
  51. key = Prefix + key;
  52. DemoWeb.MemoryCache.Set(key, data, absoluteExpiration);
  53. if (!Keys.Contains(key))
  54. {
  55. Keys.Add(key);
  56. }
  57. }
  58. /// <summary>
  59. /// 设置
  60. /// </summary>
  61. /// <param name="key"></param>
  62. /// <param name="data"></param>
  63. /// <param name="absoluteExpirationRelativeToNow"></param>
  64. public void Set(string key, object data, TimeSpan absoluteExpirationRelativeToNow)
  65. {
  66. key = Prefix + key;
  67. DemoWeb.MemoryCache.Set(key, data, absoluteExpirationRelativeToNow);
  68. if (!Keys.Contains(key))
  69. {
  70. Keys.Add(key);
  71. }
  72. }
  73. /// <summary>
  74. /// 设置
  75. /// </summary>
  76. /// <param name="key"></param>
  77. /// <param name="data"></param>
  78. /// <param name="expirationToken"></param>
  79. public void Set(string key, object data, IChangeToken expirationToken)
  80. {
  81. key = Prefix + key;
  82. DemoWeb.MemoryCache.Set(key, data, expirationToken);
  83. if (!Keys.Contains(key))
  84. {
  85. Keys.Add(key);
  86. }
  87. }
  88. /// <summary>
  89. /// 设置
  90. /// </summary>
  91. /// <param name="key"></param>
  92. /// <param name="data"></param>
  93. /// <param name="options"></param>
  94. public void Set(string key, object data, MemoryCacheEntryOptions options)
  95. {
  96. key = Prefix + key;
  97. DemoWeb.MemoryCache.Set(key, data, options);
  98. if (!Keys.Contains(key))
  99. {
  100. Keys.Add(key);
  101. }
  102. }
  103. /// <summary>
  104. /// 移除某个
  105. /// </summary>
  106. /// <param name="key"></param>
  107. public void Remove(string key)
  108. {
  109. key = Prefix + key;
  110. DemoWeb.MemoryCache.Remove(key);
  111. if (Keys.Contains(key))
  112. {
  113. Keys.Remove(key);
  114. }
  115. }
  116. /// <summary>
  117. /// 清空全部
  118. /// </summary>
  119. public void ClearAll()
  120. {
  121. foreach (var key in Keys)
  122. {
  123. DemoWeb.MemoryCache.Remove(key);
  124. }
  125. Keys.Clear();
  126. }
  127. }
复制代码
View Code

  其实接下来就可以直接利用缓存了,但为了方便利用,再建一个缓存类别的中间类来管理。

162516sd1f3c0r1vvw0c0v.gif
162516wyii2skm0s7mmmm7.gif
  1. public class UserCache
  2. {
  3. private static readonly MemoryCache Cache = new MemoryCache("User");
  4. private static TimeSpan _timeout = TimeSpan.Zero;
  5. private static TimeSpan Timeout
  6. {
  7. get
  8. {
  9. if (_timeout != TimeSpan.Zero)
  10. return _timeout;
  11. try
  12. {
  13. _timeout = TimeSpan.FromMinutes(20);
  14. return _timeout;
  15. }
  16. catch (Exception)
  17. {
  18. return TimeSpan.FromMinutes(10);
  19. }
  20. }
  21. }
  22. public static void Set(string key,string cache)
  23. {
  24. if (string.IsNullOrEmpty(cache))
  25. return;
  26. Cache.Set(key, cache, Timeout);
  27. }
  28. public static string Get(string key)
  29. {
  30. if (string.IsNullOrEmpty(key))
  31. return default(string);
  32. return Cache.Get<string>(key);
  33. }
  34. }
复制代码
UserCache

  测试是否可以正常利用:代码与截图

  1. [HttpGet]
  2. [Route("mecache")]
  3. public ActionResult ValidToken()
  4. {
  5. var key = "tkey";
  6. UserCache.Set(key, "测试数据");
  7. return Succeed(UserCache.Get(key));
  8. }
复制代码

162516mz3p7a31vhxvzz79.png

  可以清楚的看到 MemoryCache 可以正常利用。

  那么接下来将讲到如何利用 Redis 缓存。先在需要封装基础类的项目 Nuget 包中添加 StackExchange.Redis 依靠。然后添加Redis 毗连类

162516a85zbrmjjek0eqzm.gif
162516dhwzpafr53hr3p8h.gif
  1. internal class RedisConnectionFactory
  2. {
  3. public string ConnectionString { get; set; }
  4. public string Password { get; set; }
  5. public ConnectionMultiplexer CurrentConnectionMultiplexer { get; set; }
  6. /// <summary>
  7. /// 设置毗连字符串
  8. /// </summary>
  9. /// <returns></returns>
  10. public void SetConnectionString(string connectionString)
  11. {
  12. ConnectionString = connectionString;
  13. }
  14. /// <summary>
  15. /// 设置毗连字符串
  16. /// </summary>
  17. /// <returns></returns>
  18. public void SetPassword(string password)
  19. {
  20. Password = password;
  21. }
  22. public ConnectionMultiplexer GetConnectionMultiplexer()
  23. {
  24. if (CurrentConnectionMultiplexer == null || !CurrentConnectionMultiplexer.IsConnected)
  25. {
  26. if (CurrentConnectionMultiplexer != null)
  27. {
  28. CurrentConnectionMultiplexer.Dispose();
  29. }
  30. CurrentConnectionMultiplexer = GetConnectionMultiplexer(ConnectionString);
  31. }
  32. return CurrentConnectionMultiplexer;
  33. }
  34. private ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
  35. {
  36. ConnectionMultiplexer connectionMultiplexer;
  37. if (!string.IsNullOrWhiteSpace(Password) && !connectionString.ToLower().Contains("password"))
  38. {
  39. connectionString += $",password={Password}";
  40. }
  41. var redisConfiguration = ConfigurationOptions.Parse(connectionString);
  42. redisConfiguration.AbortOnConnectFail = true;
  43. redisConfiguration.AllowAdmin = false;
  44. redisConfiguration.ConnectRetry = 5;
  45. redisConfiguration.ConnectTimeout = 3000;
  46. redisConfiguration.DefaultDatabase = 0;
  47. redisConfiguration.KeepAlive = 20;
  48. redisConfiguration.SyncTimeout = 30 * 1000;
  49. redisConfiguration.Ssl = false;
  50. connectionMultiplexer = ConnectionMultiplexer.Connect(redisConfiguration);
  51. return connectionMultiplexer;
  52. }
  53. }
复制代码
RedisConnectionFactory

  再添加Redis客户端类

162517phwqwqxlxivlwiqw.gif
162517xey1ybab3byaycei.gif
  1. /// <summary>
  2. /// Redis Client
  3. /// </summary>
  4. public class RedisClient : IDisposable
  5. {
  6. public int DefaultDatabase { get; set; } = 0;
  7. private readonly ConnectionMultiplexer _client;
  8. private IDatabase _db;
  9. public RedisClient(ConnectionMultiplexer client)
  10. {
  11. _client = client;
  12. UseDatabase();
  13. }
  14. public void UseDatabase(int db = -1)
  15. {
  16. if (db == -1)
  17. db = DefaultDatabase;
  18. _db = _client.GetDatabase(db);
  19. }
  20. public string StringGet(string key)
  21. {
  22. return _db.StringGet(key).ToString();
  23. }
  24. public void StringSet(string key, string data)
  25. {
  26. _db.StringSet(key, data);
  27. }
  28. public void StringSet(string key, string data, TimeSpan timeout)
  29. {
  30. _db.StringSet(key, data, timeout);
  31. }
  32. public T Get<T>(string key)
  33. {
  34. var json = StringGet(key);
  35. if (string.IsNullOrEmpty(json))
  36. {
  37. return default(T);
  38. }
  39. return json.ToNetType<T>();
  40. }
  41. public void Set(string key, object data)
  42. {
  43. var json = data.ToJson();
  44. _db.StringSet(key, json);
  45. }
  46. public void Set(string key, object data, TimeSpan timeout)
  47. {
  48. var json = data.ToJson();
  49. _db.StringSet(key, json, timeout);
  50. }
  51. /// <summary>
  52. /// Exist
  53. /// </summary>
  54. /// <param name="key"></param>
  55. /// <returns></returns>
  56. public bool Exist(string key)
  57. {
  58. return _db.KeyExists(key);
  59. }
  60. /// <summary>
  61. /// Delete
  62. /// </summary>
  63. /// <param name="key"></param>
  64. /// <returns></returns>
  65. public bool Delete(string key)
  66. {
  67. return _db.KeyDelete(key);
  68. }
  69. /// <summary>
  70. /// Set Expire to Key
  71. /// </summary>
  72. /// <param name="key"></param>
  73. /// <param name="expiry"></param>
  74. /// <returns></returns>
  75. public bool Expire(string key, TimeSpan? expiry)
  76. {
  77. return _db.KeyExpire(key, expiry);
  78. }
  79. /// <summary>
  80. /// 计数器 如果不存在则设置值,如果存在则添加值 如果key存在且类型不为long 则会异常
  81. /// </summary>
  82. /// <param name="key"></param>
  83. /// <param name="value"></param>
  84. /// <param name="expiry">只有第一次设置有用期见效</param>
  85. /// <returns></returns>
  86. public long SetStringIncr(string key, long value = 1, TimeSpan? expiry = null)
  87. {
  88. var nubmer = _db.StringIncrement(key, value);
  89. if (nubmer == 1 && expiry != null)//只有第一次设置有用期(防止覆盖)
  90. _db.KeyExpireAsync(key, expiry);//设置有用期
  91. return nubmer;
  92. }
  93. /// <summary>
  94. /// 读取计数器
  95. /// </summary>
  96. /// <param name="key"></param>
  97. /// <returns></returns>
  98. public long GetStringIncr(string key)
  99. {
  100. var value = StringGet(key);
  101. return string.IsNullOrWhiteSpace(value) ? 0 : long.Parse(value);
  102. }
  103. /// <summary>
  104. /// 计数器-淘汰 如果不存在则设置值,如果存在则淘汰值 如果key存在且类型不为long 则会异常
  105. /// </summary>
  106. /// <param name="key"></param>
  107. /// <returns></returns>
  108. public long StringDecrement(string key, long value = 1)
  109. {
  110. var nubmer = _db.StringDecrement(key, value);
  111. return nubmer;
  112. }
  113. public void Dispose()
  114. {
  115. _client?.Dispose();
  116. }
  117. }
复制代码
RedisClient

  然后再添加Redis毗连生成工具类

162517mef1ckkejqkcd036.gif
162517yzt8b8zl8dtzba99.gif
  1. public static class RedisFactory
  2. {
  3. private static readonly object Locker = new object();
  4. private static RedisConnectionFactory factory;
  5. private static void InitRedisConnection()
  6. {
  7. try
  8. {
  9. factory = new RedisConnectionFactory();
  10. var connectionString = DemoWeb.Configuration["Redis:ConnectionString"];
  11. #if DEBUG
  12. connectionString = "127.0.0.1:6379";
  13. #endif
  14. factory.ConnectionString = connectionString;
  15. factory.Password = DemoWeb.Configuration["Redis:Pwd"];
  16. }
  17. catch (Exception e)
  18. {
  19. LogHelper.Logger.Fatal(e, "Redis毗连创建失败。");
  20. }
  21. }
  22. public static RedisClient GetClient()
  23. {
  24. //先判定一轮,淘汰锁,进步服从
  25. if (factory == null || string.IsNullOrEmpty(factory.ConnectionString))
  26. {
  27. //防止并发创建
  28. lock (Locker)
  29. {
  30. InitRedisConnection();
  31. }
  32. }
  33. return new RedisClient(factory.GetConnectionMultiplexer())
  34. {
  35. DefaultDatabase = DemoWeb.Configuration["Redis:DefaultDatabase"].ToInt()
  36. };
  37. }
  38. }
复制代码
RedisFactory

  这里要利用到前面的静态扩展方法。请自行添加 传送门 ,还需要将 Startup 类中的 Configuration 给赋值到 DemoWeb中的 Configuration 字段值来利用。

  在配置文件 appsettings.json 中添加

  1. "Redis": {
  2. "ConnectionString": "127.0.0.1:6379",
  3. "Pwd": "",
  4. "DefaultDatabase": 0
  5. }
复制代码

  再添加Redis缓存利用类

162517hrzc9sbsldp6lswp.gif
162517yi2fifybjlfzdwfx.gif
  1. /// <summary>
  2. /// Redis缓存
  3. /// </summary>
  4. public class RedisCache
  5. {
  6. private static RedisClient _client;
  7. private static RedisClient Client => _client ?? (_client = RedisFactory.GetClient());
  8. private static string ToKey(string key)
  9. {
  10. return $"Cache_redis_{key}";
  11. }
  12. /// <summary>
  13. /// 获取
  14. /// </summary>
  15. /// <typeparam name="T"></typeparam>
  16. /// <param name="key"></param>
  17. /// <returns></returns>
  18. public static T Get<T>(string key)
  19. {
  20. try
  21. {
  22. var redisKey = ToKey(key);
  23. return Client.Get<T>(redisKey);
  24. }
  25. catch (Exception e)
  26. {
  27. LogHelper.Logger.Fatal(e, "RedisCache.Get \n key:{0}", key);
  28. return default(T);
  29. }
  30. }
  31. /// <summary>
  32. /// 尝试获取
  33. /// </summary>
  34. /// <typeparam name="T"></typeparam>
  35. /// <param name="key"></param>
  36. /// <param name="result"></param>
  37. /// <returns></returns>
  38. private static T TryGet<T>(string key, out bool result)
  39. {
  40. result = true;
  41. try
  42. {
  43. var redisKey = ToKey(key);
  44. return Client.Get<T>(redisKey);
  45. }
  46. catch (Exception e)
  47. {
  48. LogHelper.Logger.Fatal(e, "RedisCache.TryGet \n key:{0}", key);
  49. result = false;
  50. return default(T);
  51. }
  52. }
  53. /// <summary>
  54. /// 获取
  55. /// </summary>
  56. /// <typeparam name="T"></typeparam>
  57. /// <param name="key"></param>
  58. /// <param name="setFunc"></param>
  59. /// <param name="expiry"></param>
  60. /// <param name="resolver"></param>
  61. /// <returns></returns>
  62. public static T Get<T>(string key, Func<T> setFunc, TimeSpan? expiry = null)
  63. {
  64. var redisKey = ToKey(key);
  65. var result = TryGet<T>(redisKey, out var success);
  66. if (success && result == null)
  67. {
  68. result = setFunc();
  69. try
  70. {
  71. Set(redisKey, result, expiry);
  72. }
  73. catch (Exception e)
  74. {
  75. LogHelper.Logger.Fatal(e, "RedisCache.Get<T> \n key:{0}", key);
  76. }
  77. }
  78. return result;
  79. }
  80. /// <summary>
  81. /// 设置
  82. /// </summary>
  83. /// <typeparam name="T"></typeparam>
  84. /// <param name="key"></param>
  85. /// <param name="value"></param>
  86. /// <param name="expiry"></param>
  87. /// <returns></returns>
  88. public static bool Set<T>(string key, T value, TimeSpan? expiry = null)
  89. {
  90. var allRedisKey = ToKey("||Keys||");
  91. var redisKey = ToKey(key);
  92. var allkeyRedisValue = Client.StringGet(allRedisKey);
  93. var keys = allkeyRedisValue.ToNetType<List<string>>() ?? new List<string>();
  94. if (!keys.Contains(redisKey))
  95. {
  96. keys.Add(redisKey);
  97. Client.Set(allRedisKey, keys);
  98. }
  99. if (expiry.HasValue)
  100. {
  101. Client.StringSet(redisKey, value.ToJson(), expiry.Value);
  102. }
  103. else
  104. {
  105. Client.StringSet(redisKey, value.ToJson());
  106. }
  107. return true;
  108. }
  109. /// <summary>
  110. /// 重新设置逾期时间
  111. /// </summary>
  112. /// <param name="key"></param>
  113. /// <param name="expiry"></param>
  114. public static void ResetItemTimeout(string key, TimeSpan expiry)
  115. {
  116. var redisKey = ToKey(key);
  117. Client.Expire(redisKey, expiry);
  118. }
  119. /// <summary>
  120. /// Exist
  121. /// </summary>
  122. /// <param name="key">原始key</param>
  123. /// <returns></returns>
  124. public static bool Exist(string key)
  125. {
  126. var redisKey = ToKey(key);
  127. return Client.Exist(redisKey);
  128. }
  129. /// <summary>
  130. /// 计数器 增长 能设置逾期时间的都设置逾期时间
  131. /// </summary>
  132. /// <param name="key"></param>
  133. /// <param name="value"></param>
  134. /// <param name="expiry"></param>
  135. /// <returns></returns>
  136. public static bool SetStringIncr(string key, long value = 1, TimeSpan? expiry = null, bool needRest0 = false)
  137. {
  138. var redisKey = ToKey(key);
  139. try
  140. {
  141. if (expiry.HasValue)
  142. {
  143. if (Exist(key) && needRest0)
  144. {
  145. var exitValue = GetStringIncr(key);
  146. Client.SetStringIncr(redisKey, value - exitValue, expiry.Value);
  147. }
  148. else
  149. {
  150. Client.SetStringIncr(redisKey, value, expiry.Value);
  151. }
  152. }
  153. else
  154. {
  155. if (Exist(key) && needRest0)
  156. {
  157. var exitValue = GetStringIncr(key);
  158. Client.SetStringIncr(redisKey, value - exitValue);
  159. }
  160. else
  161. {
  162. Client.SetStringIncr(redisKey, value);
  163. }
  164. }
  165. }
  166. catch (Exception e)
  167. {
  168. LogHelper.Logger.Fatal($"计数器-增长错误,缘故起因:{e.Message}");
  169. return false;
  170. }
  171. return true;
  172. }
  173. /// <summary>
  174. /// 读取计数器
  175. /// </summary>
  176. /// <param name="key"></param>
  177. /// <returns></returns>
  178. public static long GetStringIncr(string key)
  179. {
  180. var redisKey = ToKey(key);
  181. return Client.GetStringIncr(redisKey);
  182. }
  183. /// <summary>
  184. /// 计数器 - 淘汰
  185. /// </summary>
  186. /// <param name="key"></param>
  187. /// <returns></returns>
  188. public static bool StringDecrement(string key, long value = 1)
  189. {
  190. var redisKey = ToKey(key);
  191. try
  192. {
  193. Client.StringDecrement(redisKey, value);
  194. return true;
  195. }
  196. catch (Exception e)
  197. {
  198. LogHelper.Logger.Fatal($"计数器-淘汰错误,缘故起因:{e.Message}");
  199. return false;
  200. }
  201. }
  202. /// <summary>
  203. /// 删除
  204. /// </summary>
  205. /// <param name="key"></param>
  206. /// <returns></returns>
  207. public static bool Delete(string key)
  208. {
  209. var redisKey = ToKey(key);
  210. return Client.Delete(redisKey);
  211. }
  212. /// <summary>
  213. /// 清空
  214. /// </summary>
  215. public static void Clear()
  216. {
  217. //由于codis不支持keys之类的下令,以是只能本身记载下来,然后通过这个来整理。
  218. var redisKey = ToKey("||Keys||");
  219. var keys = Client.Get<List<string>>(redisKey);
  220. var notExists = new List<string>();
  221. foreach (var key in keys)
  222. {
  223. if (Client.Exist(key))
  224. Client.Delete(key);
  225. else
  226. notExists.Add(key);
  227. }
  228. if (notExists.Count > 0)
  229. {
  230. keys.RemoveAll(s => notExists.Contains(s));
  231. Client.Set(redisKey, keys);
  232. }
  233. }
  234. }
复制代码
RedisCache

  到这来根本就快可以拿来测试是否可以用了。但是条件是得把 Redis 给运行起来。

  将上面的 Redis安装包安装,并启动所安装文件夹中的 redis-server.exe 步伐,若出现闪退情况,就运行 redis-cli.exe 步伐,然后输入 shutdown 按下回车,重新运行 redis-server.exe 步伐,就会出现这个界面。

162517r4mrmu9mkdyojoco.png

  到这来,添加一个测试方法来看看结果。借助Redis可视化工具检察结果如下

162517qlkbua8s6jzxgnn6.png

  测试完善成功,由于时间题目,上面 RedisCache只有字符串的方法,没有加别的类型的方法。有需要的本身加咯~

  在下一篇中将先容如何在NetCore中如何利用 过滤器来举行权限验证

  有需要源码的在下方评论或私信~给我的SVN访客账户暗码下载,代码未放在GitHub上。svn中新加上了Redis安装包及可视化工具。







来源:https://www.cnblogs.com/levywang/archive/2019/09/11/coreframe_8.html
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则