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

浙公网安备 33010602011771号