441 lines
12 KiB
C#
441 lines
12 KiB
C#
using NewLife.Caching;
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace RedisHelper
|
|
{
|
|
public class RedisCache : ICache
|
|
{
|
|
public FullRedis fullRedis = null;
|
|
private readonly ILogger<RedisCache> _logger;
|
|
|
|
public RedisCache(RedisUrl config, ILogger<RedisCache> logger)
|
|
{
|
|
_logger = logger;
|
|
fullRedis = FullRedis.Create(config.url);
|
|
fullRedis.MaxMessageSize = 16 * 1024 * 1024;
|
|
}
|
|
|
|
public FullRedis GetFullRedis()
|
|
{
|
|
return fullRedis;
|
|
}
|
|
|
|
~RedisCache()
|
|
{
|
|
fullRedis.Dispose();
|
|
}
|
|
public void StartPipeline()
|
|
{
|
|
fullRedis.StartPipeline();
|
|
}
|
|
|
|
public long IncrBy(string key, long value)
|
|
{
|
|
return fullRedis.Increment(key, value);
|
|
}
|
|
|
|
public bool SetAdd<T>(string key, T value)
|
|
{
|
|
var result = fullRedis.SADD(key, value);
|
|
return result > 0;
|
|
}
|
|
|
|
public bool SetContains<T>(string key, T value)
|
|
{
|
|
return fullRedis.SISMEMBER(key, value) > 0;
|
|
}
|
|
|
|
public bool SetRemove<T>(string key, T value)
|
|
{
|
|
return fullRedis.SREM(key, value) > 0;
|
|
}
|
|
|
|
public long SetCount(string key)
|
|
{
|
|
return fullRedis.SCARD(key);
|
|
}
|
|
|
|
public List<T> SetMembers<T>(string key)
|
|
{
|
|
return fullRedis.SMEMBERS<T>(key).ToList();
|
|
}
|
|
|
|
private static readonly System.Text.Json.JsonSerializerOptions _jsonOptions = new()
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
WriteIndented = false
|
|
};
|
|
|
|
private static bool IsSimpleType(Type t) =>
|
|
t == typeof(string) || t == typeof(long) || t == typeof(int) || t == typeof(bool) || t == typeof(double);
|
|
|
|
public T Get<T>(string key)
|
|
{
|
|
try
|
|
{
|
|
if (IsSimpleType(typeof(T)))
|
|
return fullRedis.Get<T>(key);
|
|
|
|
var json = fullRedis.Get<string>(key);
|
|
if (json == null) return default;
|
|
return System.Text.Json.JsonSerializer.Deserialize<T>(json, _jsonOptions);
|
|
}
|
|
catch
|
|
{
|
|
return default;
|
|
}
|
|
}
|
|
public IDictionary<string,T> GetAll<T>(List<string> keys)
|
|
{
|
|
try
|
|
{
|
|
if (IsSimpleType(typeof(T)))
|
|
return fullRedis.GetAll<T>(keys);
|
|
|
|
var strDict = fullRedis.GetAll<string>(keys);
|
|
if (strDict == null) return null;
|
|
var result = new Dictionary<string, T>();
|
|
foreach (var kv in strDict)
|
|
{
|
|
if (kv.Value != null)
|
|
result[kv.Key] = System.Text.Json.JsonSerializer.Deserialize<T>(kv.Value, _jsonOptions);
|
|
}
|
|
return result;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public bool Insert<T>(string key, T data)
|
|
{
|
|
if (IsSimpleType(typeof(T)))
|
|
return fullRedis.Set<T>(key, data);
|
|
|
|
var json = System.Text.Json.JsonSerializer.Serialize(data, _jsonOptions);
|
|
return fullRedis.Set<string>(key, json);
|
|
}
|
|
|
|
public bool Insert<T>(string key, T data, int expireSeconds)
|
|
{
|
|
if (IsSimpleType(typeof(T)))
|
|
return fullRedis.Set<T>(key, data, expireSeconds);
|
|
|
|
var json = System.Text.Json.JsonSerializer.Serialize(data, _jsonOptions);
|
|
return fullRedis.Set<string>(key, json, expireSeconds);
|
|
}
|
|
|
|
public bool Insert<T>(string key, T data, TimeSpan expireSeconds)
|
|
{
|
|
if (IsSimpleType(typeof(T)))
|
|
return fullRedis.Set<T>(key, data, expireSeconds);
|
|
|
|
var json = System.Text.Json.JsonSerializer.Serialize(data, _jsonOptions);
|
|
return fullRedis.Set<string>(key, json, expireSeconds);
|
|
}
|
|
|
|
public int Remove(string key)
|
|
{
|
|
return fullRedis.Remove(key);
|
|
}
|
|
|
|
|
|
public void Clear(string pattern, int count = 1000)
|
|
{
|
|
try
|
|
{
|
|
var keys = fullRedis.Search(pattern, count).ToArray();
|
|
if (keys.Any())
|
|
{
|
|
fullRedis.Remove(keys);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.LogError(e, "按表达式清理Redis键失败 pattern={Pattern} count={Count}", pattern, count);
|
|
}
|
|
}
|
|
|
|
public IEnumerable<string> GetPatternKey(string pattern, int count = 1000)
|
|
{
|
|
return fullRedis.Search(pattern, count).ToArray();
|
|
}
|
|
|
|
public IEnumerable<T> GetPatternList<T>(string pattern, int count = 1000)
|
|
{
|
|
var lstKey = fullRedis.Search(pattern, count).ToArray();
|
|
|
|
return lstKey.Select(item => fullRedis.Get<T>(item)).ToList();
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
{
|
|
fullRedis.Clear();
|
|
}
|
|
|
|
public bool Exists(string key)
|
|
{
|
|
return fullRedis.ContainsKey(key);
|
|
}
|
|
|
|
public IList<T> GetList<T>(string key)
|
|
{
|
|
return fullRedis.GetList<T>(key);
|
|
}
|
|
|
|
public bool AddToList<T>(string key, T t)
|
|
{
|
|
try
|
|
{
|
|
var lst = fullRedis.GetList<T>(key);
|
|
lst.Add(t);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public bool InitDataToList<T>(string key, List<T> t)
|
|
{
|
|
try
|
|
{
|
|
fullRedis.Remove(key);
|
|
var lst = fullRedis.GetList<T>(key);
|
|
lst.Clear();
|
|
foreach (var item in t)
|
|
{
|
|
lst.Add(item);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public bool UpdateDataToList<T>(string key, T t, Func<T, bool> predicate)
|
|
{
|
|
try
|
|
{
|
|
var lst = fullRedis.GetList<T>(key);
|
|
|
|
var data = lst.Where(predicate);
|
|
foreach (var item in data)
|
|
{
|
|
lst.Remove(item);
|
|
|
|
}
|
|
|
|
lst.Add(t);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool RemoveFromList<T>(string key, Func<T, bool> predicate)
|
|
{
|
|
var result = false;
|
|
var lst = fullRedis.GetList<T>(key);
|
|
var data = lst.Where(predicate);
|
|
if (data != null)
|
|
{
|
|
foreach (var item in data)
|
|
{
|
|
result = lst.Remove(item);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool InitDataToDictionary<T>(string key, IDictionary<string, T> t)
|
|
{
|
|
try
|
|
{
|
|
fullRedis.Remove(key);
|
|
var lst = fullRedis.GetDictionary<T>(key);
|
|
// lst.Clear();
|
|
foreach (var item in t)
|
|
{
|
|
lst.Add(item.Key, item.Value);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public bool UpdateDataToDictionary<T>(string key, T t, string dataKey)
|
|
{
|
|
try
|
|
{
|
|
var lst = fullRedis.GetDictionary<T>(key);
|
|
lst.Remove(dataKey);
|
|
lst.Add(dataKey, t);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool RemoveFromDictionary<T>(string key, string dataKey)
|
|
{
|
|
var lst = fullRedis.GetDictionary<T>(key);
|
|
return lst.Remove(dataKey);
|
|
}
|
|
|
|
|
|
public T GetFromDictionary<T>(string key, string dataKey)
|
|
{
|
|
var lst = fullRedis.GetDictionary<T>(key);
|
|
if (lst.ContainsKey(dataKey))
|
|
{
|
|
return lst[dataKey];
|
|
}
|
|
else
|
|
{
|
|
return default(T);
|
|
}
|
|
}
|
|
|
|
public ICollection<T> GetListFromDictionary<T>(string key)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
return dict.Values;
|
|
}
|
|
|
|
public IEnumerable<T> GetListFromDictionaryByFilter<T>(string key, Func<T, bool> filter)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
return dict.Values.Where(filter);
|
|
}
|
|
|
|
|
|
public int GetListCountFromDictionaryByFilter<T>(string key, Func<T, bool> filter)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
return dict.Values.Where(filter).Count();
|
|
}
|
|
|
|
|
|
|
|
public Tuple<IEnumerable<T>,int> GetPageDescendingListFromDictionary<T,Tkey>(string key, int pageIndex, int pageSize, Func<T, bool> filter,
|
|
Func<T,Tkey> sort)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
var count = dict.Values.Where(filter).Count();
|
|
var data= dict.Values.Where(filter)
|
|
.OrderByDescending(sort)
|
|
.Skip((pageIndex - 1) * pageSize).Take(pageSize);
|
|
return new Tuple<IEnumerable<T>, int>(data, count);
|
|
}
|
|
|
|
public Tuple<IEnumerable<T>,int> GetPageDescendingListFromDictionary<T,Tkey>(string key, int pageIndex, int pageSize, Func<T, bool> filter,
|
|
Func<T,Tkey> sort,int skipCount)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
var count = dict.Values.Where(filter).Count();
|
|
var data= dict.Values.Where(filter)
|
|
.OrderByDescending(sort)
|
|
.Skip((pageIndex - 1) * pageSize+skipCount).Take(pageSize);
|
|
return new Tuple<IEnumerable<T>, int>(data, count);
|
|
}
|
|
|
|
|
|
public Tuple<IEnumerable<T>, int> GetPageListFromDictionary<T, Tkey>(string key, int pageIndex, int pageSize,
|
|
Func<T, bool> filter,
|
|
Func<T, Tkey> sort)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
var count = dict.Values.Where(filter).Count();
|
|
|
|
var data = dict.Values.Where(filter)
|
|
.OrderBy(sort)
|
|
.Skip((pageIndex - 1) * pageSize).Take(pageSize);
|
|
|
|
return new Tuple<IEnumerable<T>, int>(data, count);
|
|
}
|
|
|
|
|
|
public Tuple<IEnumerable<T>, int> GetPageListFromDictionary<T, Tkey>(string key, int pageIndex, int pageSize,
|
|
Func<T, bool> filter,
|
|
Func<T, Tkey> sort,int skipCount)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
var count = dict.Values.Where(filter).Count();
|
|
|
|
var data = dict.Values.Where(filter)
|
|
.OrderBy(sort)
|
|
.Skip((pageIndex - 1) * pageSize+skipCount).Take(pageSize);
|
|
|
|
return new Tuple<IEnumerable<T>, int>(data, count);
|
|
}
|
|
|
|
public IEnumerable<T> GetListFromDictionary<T, Tkey>(string key, int pageIndex, int pageSize,
|
|
Func<T, bool> filter,
|
|
Func<T, Tkey> sort)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
var count = dict.Values.Where(filter).Count();
|
|
|
|
var data = dict.Values.Where(filter)
|
|
.OrderBy(sort)
|
|
.Skip((pageIndex - 1) * pageSize).Take(pageSize);
|
|
|
|
return data;
|
|
}
|
|
|
|
|
|
public IEnumerable<T> GetDescendingListFromDictionary<T,Tkey>(string key, int pageIndex, int pageSize, Func<T, bool> filter,
|
|
Func<T,Tkey> sort)
|
|
{
|
|
var dict = fullRedis.GetDictionary<T>(key);
|
|
var data= dict.Values.Where(filter)
|
|
.OrderByDescending(sort)
|
|
.Skip((pageIndex - 1) * pageSize).Take(pageSize);
|
|
return data;
|
|
}
|
|
|
|
|
|
private string Temp="HS:Temp:{0}";
|
|
|
|
public bool AddTempContent<T>(string tempId, T data, TimeSpan timeSpan)
|
|
{
|
|
string key = string.Format(Temp, tempId);
|
|
|
|
return Insert(key, data, timeSpan);
|
|
|
|
}
|
|
|
|
|
|
public T GetTempContent<T>(string tempId)
|
|
{
|
|
string key = string.Format(Temp, tempId);
|
|
return Get<T>(key);
|
|
}
|
|
}
|
|
}
|