using BaseOUDAL; using Newtonsoft.Json; using System.Collections.Concurrent; namespace YLErp.Modules.DataCacheModule { /// /// Represents a manager for caching between HTTP requests (long term caching) /// public class DBCacheManager { public const int CacheTimeout = 3 * 60; private List TradeDetailReport = new List() { CacheTable.CCEmail,CacheTable.TradeDetailsBiaoTou,CacheTable.TradeDetailsBiaoWei, CacheTable.TradeDetailsLuoKuan,CacheTable.TradeDetailsSendUser,CacheTable.TradeDerailsNeedAppendix }; private List TradeSwapDetailReport = new List() { CacheTable.SwapCCEmail,CacheTable.TradeSwapDetailsBiaoTou,CacheTable.TradeSwapDetailsBiaoWei, CacheTable.TradeSwapDetailsLuoKuan,CacheTable.TradeSwapDetailsSendUser,CacheTable.TradeDerailsNeedAppendix }; private List ClientBalanceReport = new List() { CacheTable.DingShiDesc,CacheTable.TradeMarketSheets,CacheTable.TradeMarketSendUser, CacheTable.LuoKuanDesc,CacheTable.MarginLuoKuanDesc,CacheTable.ClientBalanceReportTiltle,CacheTable.MarketCCEmail }; public static readonly DBCacheManager Single; static DBCacheManager() { Single = new DBCacheManager(); } readonly ConcurrentDictionary _cacheDic; protected DBCacheManager() { _cacheDic = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); } ConcurrentDictionary CacheDic { get { if (_cacheDic.Count < 1) { using (ErpBaseContext db = new ErpBaseContext()) { var caches = db.CacheTable.Where(c => c.ValidateDate >= DateTime.Now).ToArray(); foreach (var item in caches) { if (!string.IsNullOrEmpty(item.Key)) { _cacheDic.TryAdd(item.Key + item.TemplateName, item); } } if (_cacheDic.Count < 1) { var item = new CacheTable() { Key = "$" + Guid.NewGuid().ToString() }; _cacheDic.TryAdd(item.Key, item); } } } return _cacheDic; } } public string GetStr(string key, string template = "默认") { if (string.IsNullOrEmpty(key)) { return string.Empty; } if (CacheDic.TryGetValue(key + template, out CacheTable ca)) { return ca.Data; } using (ErpBaseContext db = new ErpBaseContext()) { ca = db.CacheTable.FirstOrDefault(c => c.Key == key && c.TemplateName == template); if (ca == null) { return string.Empty; } CacheDic.AddOrUpdate(key + template, ca, (k, old) => ca); return ca.Data; } } public void UpdateObj(string key, string value, string template = "默认") { if (string.IsNullOrEmpty(key)) { return; } using (ErpBaseContext db = new ErpBaseContext()) { var caObj = db.CacheTable.FirstOrDefault(c => c.Key == key && c.TemplateName == template); if (caObj == null) { caObj = new CacheTable { Key = key, TemplateName = template, CreateDate = DateTime.Now }; db.CacheTable.Add(caObj); } caObj.Data = value; caObj.ValidateDate = DateTime.Now.AddSeconds(CacheTimeout); db.SaveChanges(); CacheDic.AddOrUpdate(key + template, caObj, (k, old) => caObj); } } /// /// Gets or sets the value associated with the specified key. /// /// Type /// The key of the value to get. /// The value associated with the specified key. public virtual T Get(string key, string template = "默认") where T : new() { if (!string.IsNullOrEmpty(key) && CacheDic.TryGetValue(key + template, out CacheTable ca)) { return JsonConvert.DeserializeObject(ca.Data); } return new T(); } /// /// Adds the specified key and object to the cache. /// /// key /// Data /// Cache time public virtual void Set(string key, object data, int cacheTime = CacheTimeout, string template = "默认") { if (string.IsNullOrEmpty(key) || data == null) { return; } lock (CacheDic) { var dataStr = string.Empty; if (data == null) { dataStr = string.Empty; } else if (data is string str) { dataStr = str; } else { dataStr = JsonConvert.SerializeObject(data); } using (ErpBaseContext db = new ErpBaseContext()) { var ca = db.CacheTable.FirstOrDefault(c => c.Key == key && c.TemplateName == template); if (ca == null) { ca = new CacheTable { Key = key, TemplateName = template, CreateDate = DateTime.Now }; db.CacheTable.Add(ca); } ca.Data = dataStr; ca.ValidateDate = DateTime.Now.AddSeconds(cacheTime); db.SaveChanges(); CacheDic.AddOrUpdate(key + template, ca, (k, old) => ca); } } } /// /// Gets a value indicating whether the value associated with the specified key is cached /// /// key /// Result public virtual bool IsSet(string key, string template = "默认") { return !string.IsNullOrEmpty(key + template) && CacheDic.ContainsKey(key + template); } /// /// Removes the value with the specified key from the cache /// /// /key public virtual void Remove(string key, string template = "默认") { if (string.IsNullOrEmpty(key)) { return; } CacheDic.TryRemove(key, out CacheTable cacheTable); using (ErpBaseContext db = new ErpBaseContext()) { db.CacheTable.Where(n => n.Key == key && n.TemplateName == template).ToArray() .Where(c => c.Key == key).ToList().ForEach(c => { c.ValidateDate = DateTime.MinValue; }); db.SaveChanges(); } } public virtual List GetTemplateNames(string reportType) { List fliterList = new List(); switch (reportType) { case "交易明细": fliterList = TradeDetailReport; break; case "互换明细": fliterList = TradeSwapDetailReport; break; case "结算报告": fliterList = ClientBalanceReport; break; default: throw new ServiceException("错误的报告类型"); } using (ErpBaseContext db = new ErpBaseContext()) { return db.CacheTable.Where(o => fliterList.Contains(o.Key)).Select(o => o.TemplateName).Distinct().ToList(); } } public virtual void RemoveTemplate(string reportType, string template) { List fliterList = new List(); switch (reportType) { case "交易明细": fliterList = TradeDetailReport; break; case "互换明细": fliterList = TradeSwapDetailReport; break; case "结算报告": fliterList = ClientBalanceReport; break; default: throw new ServiceException("错误的报告类型"); } using (ErpBaseContext db = new ErpBaseContext()) { var needDel = db.CacheTable.Where(o => fliterList.Contains(o.Key) && o.TemplateName == template); if (needDel.Count() > 0) { db.CacheTable.RemoveRange(needDel); db.SaveChanges(); } else { throw new ServiceException("不存在 " + needDel + " 模板"); } } } } }