SqlSugar本地缓存查询实现方式
有C#的国产ORM SqlSugar 好久了,实在话还不错,不过毕竟是早期产物不能过分要求规范化,有些项目查询语句需要用到缓存,官方是redis,我写了个本地缓存借助ConcurrentBag,因为有的项目禁止过分依赖三方组件,以下是我实现的方法,可供大家参考:
using SqlSugar; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; namespace Common { /// <summary> /// SqlSugar本地缓存实现 /// </summary> public class SqlSugarLocalCache : ICacheService { public static ConcurrentBag<Tuple<string, object, DateTime>> CacheList = new ConcurrentBag<Tuple<string, object, DateTime>>(); private readonly DateTime now; /// <summary> /// 最大缓存天数 /// </summary> public int MaxCacheDays { get; set; } = 3; public SqlSugarLocalCache() { now = DateTime.Now; } public void Add<V>(string key, V value) { ExpiredMonitoring(); if (MaxCacheDays == 0) MaxCacheDays = 3; CacheList.Add(new Tuple<string, object, DateTime>(key, value, now.AddDays(MaxCacheDays))); } public void Add<V>(string key, V value, int cacheDurationInSeconds) { ExpiredMonitoring(); if (MaxCacheDays > 0) { int s = GetDaysSeconds(MaxCacheDays); if (s < cacheDurationInSeconds) cacheDurationInSeconds = s; } CacheList.Add(new Tuple<string, object, DateTime>(key, value, now.AddSeconds(cacheDurationInSeconds))); } public bool ContainsKey<V>(string key) { ExpiredMonitoring(); return CacheList.Any(m => m.Item1 == key); } public V Get<V>(string key) { ExpiredMonitoring(); return (V)CacheList.Where(m => m.Item1 == key).FirstOrDefault()?.Item2; } public IEnumerable<string> GetAllKey<V>() { ExpiredMonitoring(); return CacheList.Where(m => m.Item1.StartsWith("SqlSugarDataCache.")).Select(m => m.Item1); } public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue) { ExpiredMonitoring(); if (MaxCacheDays > 0) { int s = GetDaysSeconds(MaxCacheDays); if (s < cacheDurationInSeconds) cacheDurationInSeconds = s; } V result; if (ContainsKey<V>(cacheKey)) { result = Get<V>(cacheKey); result = result == null ? create() : result; } else { result = create(); Add(cacheKey, result, cacheDurationInSeconds); } return result; } public void Remove<V>(string key) { ExpiredMonitoring(); if (ContainsKey<V>(key)) { var result = CacheList.Where(m => m.Item1 == key).FirstOrDefault(); CacheList.TryTake(out result); } } /// <summary> /// 过期监听 /// </summary> private void ExpiredMonitoring() { var expList = CacheList.Where(m => m.Item3 < now).ToList(); int l = expList.Count; for (int i = 0; i < l; i++) { var item = expList[i]; CacheList.TryTake(out item); } } /// <summary> /// 获取指定天数秒数 /// </summary> /// <param name="days">指定天数</param> /// <returns></returns> private static int GetDaysSeconds(int days) { return 60 * 60 * 24 * days; } } }