using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Configuration; using System.Text; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using GWMS.Data; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using System.Diagnostics; using NLog; using GWMS.Data.DTO; using GWMS.Data.DatabaseModels; using static GWMS.Data.IobObjects; using System.Globalization; namespace GWMS.UI.Data { public class GWMSDataService : IDisposable { #region Private Fields private static IConfiguration _configuration; private static ILogger _logger; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IDistributedCache distributedCache; private readonly IMemoryCache memoryCache; /// /// Durata assoluta massima della cache IN SECONDI /// private int chAbsExp = 60 * 5; /// /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa /// NON estende oltre il tempo massimo di validità della cache (chAbsExp) /// private int chSliExp = 60 * 1; #endregion Private Fields #region Protected Fields protected static string connStringBBM = ""; #endregion Protected Fields #region Public Fields public static GWMS.Data.Controllers.GWMSController dbController; #endregion Public Fields #region Public Constructors public GWMSDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) { _logger = logger; _configuration = configuration; // conf cache this.memoryCache = memoryCache; this.distributedCache = distributedCache; // conf DB string connStr = _configuration.GetConnectionString("GWMS.Data"); if (string.IsNullOrEmpty(connStr)) { _logger.LogError("ConnString empty!"); } else { dbController = new GWMS.Data.Controllers.GWMSController(configuration); } } #endregion Public Constructors #region Private Methods private DistributedCacheEntryOptions cacheOpt(bool fastCache) { var numSecAbsExp = fastCache ? chAbsExp : chAbsExp * 10; var numSecSliExp = fastCache ? chSliExp : chSliExp * 10; return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); } /// /// Recupera PlantDTO e aggiorno valori attuali (se presente...) /// ATTENZIONE: i dati sono sempre ricevuti PER SINGOLO PlantId!!! /// /// private async Task updateCurrDTO(List newItems) { DateTime adesso = DateTime.Now; List dbResult = new List(); int PlantId = newItems.FirstOrDefault().PlantId; string cacheKey = "DATA:PLANTS:ListDTO"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); // ora ciclo x ogni flusso/macchina l'ultimo record List lastByFlux = newItems .OrderByDescending(x => x.DtEvent) .GroupBy(g => g.FluxType) .Select(s => s.First()) .ToList(); // aggiorno il DTO x i valori trovati... var currDto = dbResult.Where(x => x.PlantId == PlantId).FirstOrDefault(); // verifico SE c'è Level var lastLev = lastByFlux.Where(x => x.FluxType == "Level").FirstOrDefault(); if (lastLev != null) { currDto.LevelAct = lastLev.ValNumber; currDto.LastUpdate = adesso; } // verifico SE c'è MainPress var lastMain = lastByFlux.Where(x => x.FluxType == "MainPress").FirstOrDefault(); if (lastMain != null) { if (currDto.PressAct.ContainsKey("Main")) { currDto.PressAct["Main"] = lastMain.ValNumber; } else { currDto.PressAct.Add("Main", lastMain.ValNumber); } } // verifico SE c'è PressBH var lastBH = lastByFlux.Where(x => x.FluxType == "PressBH").FirstOrDefault(); if (lastBH != null) { if (currDto.PressAct.ContainsKey("BH")) { currDto.PressAct["BH"] = lastBH.ValNumber; } else { currDto.PressAct.Add("BH", lastBH.ValNumber); } } // verifico SE c'è PressBL var lastBL = lastByFlux.Where(x => x.FluxType == "PressBL").FirstOrDefault(); if (lastBL != null) { if (currDto.PressAct.ContainsKey("BL")) { currDto.PressAct["BL"] = lastBL.ValNumber; } else { currDto.PressAct.Add("BL", lastBL.ValNumber); } } // salvo DTO! rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); } } #endregion Private Methods #region Protected Methods /// /// Hash dati EXE TASK x la macchina specificata /// /// /// protected static string exeTaskHash(string idxMacchina) { return mHash(string.Format("ExeTask:{0}", idxMacchina)); } protected async Task checkCreateOrders() { bool fatto = false; List NewOrders = new List(); DateTime adesso = DateTime.Now; int supplierId = 1; int transporterId = 1; double qtyOrd = 0; // faccio ciclo x tutti gli impianti List currPlantData = await PlantsGetAll(); List fullWeekPlan = WeekPlanGet().Result; foreach (var item in currPlantData) { // recupero ordini x il plant var currOrderOpen = await OrdersGetOpen(item.PlantId); // calcolo delta ordinato qtyOrd = currOrderOpen.Sum(x => x.OrderQty); // verifico il livello attuale + i valori degli ordini APERTI rispetto al livello di riordino... if (item.LevelAct + qtyOrd < item.LevelReorder) { // (FARE !!! VERIFICA!!!!) // calcolo supplier/transporter da tab WeekPlan var dailyPlan = fullWeekPlan.Where(x => x.PlantId == item.PlantId && (int)x.DayNum == ((int)adesso.DayOfWeek + 1)).FirstOrDefault(); if (dailyPlan != null) { supplierId = dailyPlan.SupplierId; transporterId = dailyPlan.TransporterId; } else { supplierId = 1; transporterId = 1; } // stacco un NUOVO ordine di quantità finita NewOrders.Add(new OrderModel() { DtOrder = adesso, OrderQty = item.OrderQtyStd, PlantId = item.PlantId, OrderCode = $"O{item.PlantCode}{adesso:yyMMddHHmm}", OrderDesc = $"Ordine {item.PlantDesc} - {adesso}", SupplierId = supplierId, TransporterId = transporterId }); } } if (NewOrders.Count > 0) { // effettuo inserimento ordini! dbController.OrderInsert(NewOrders); // invio email x ogni fornitore x i NUOVI ordini inseriti var orders4supp = NewOrders.GroupBy(g => g.SupplierId).FirstOrDefault(); foreach (var item in orders4supp) { // invio email di notifica nuovi ordini inseriti } // invio email x ogni fornitore x i NUOVI ordini inseriti var orders4transp = NewOrders.GroupBy(g => g.TransporterId).FirstOrDefault(); foreach (var item in orders4transp) { // invio email di notifica nuovi ordini inseriti } fatto = true; } return fatto; } protected string getCacheKey(string TableName, SelectOrderData CurrFilter) { string answ = $"{TableName}:P_{CurrFilter.PlantId:00}:S_{CurrFilter.SupplierId:00}:T_{CurrFilter.TransporterId:00}:D_{CurrFilter.DateStart:yyyyMMddHHmm}_{CurrFilter.DateEnd:yyyyMMddHHmm}"; return answ; } protected async Task> PlantLogGetLastByFlux(int PlantId) { List lastValues = new List(); // cerco in cache string cacheKey = $"DATA:PLANTS:LastFlux:{PlantId}"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); lastValues = JsonConvert.DeserializeObject>(rawData); } // altrimenti DB e salvo... else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); lastValues = dbController.PlantLogGetLastByFlux(PlantId); rawData = JsonConvert.SerializeObject(lastValues); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per PlantLogGetLastByFlux: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(lastValues); } #endregion Protected Methods #region Public Methods /// /// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...) /// /// /// public static string mHash(string dataType) { return $"DATA:{dataType}"; } /// /// effettua verifica x tutti i plant, se livello > livello riordino e NON ci sono ordini APERTI in arrivo --> lancia ordine /// public async Task checkLevels() { bool fatto = false; // effettuo verifica veto ricalcolo ordini da cache... DateTime adesso = DateTime.Now; DateTime vetoCheck = adesso.AddMinutes(1); string cacheKey = "DATA:CHECKLEVEL"; string rawData; try { var redisDataList = await distributedCache.GetAsync(cacheKey); // se non ho veto --> controllo if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); vetoCheck = JsonConvert.DeserializeObject(rawData); } else { vetoCheck = adesso.AddMinutes(-1); } if (adesso > vetoCheck) { fatto = await checkCreateOrders(); // imposto nuovo veto a 5 min... vetoCheck = adesso.AddMinutes(5); rawData = JsonConvert.SerializeObject(vetoCheck); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); } } catch { } return fatto; } public async Task> ConfigGetAll() { //return Task.FromResult(dbController.ActionsGetAll()); List dbResult = new List(); string cacheKey = "DATA:CONFIG"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetConfig(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per ConfigGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public PlantLogModel convertFluxToPL(int plantId, flogData origData) { // cerco di ottenere un val in cifre double valDbl = 0; NumberStyles style = NumberStyles.Number; CultureInfo culture = CultureInfo.CreateSpecificCulture("it-IT"); double.TryParse(origData.valore.Replace(".", ","), style, culture, out valDbl); TimeSpan delta = origData.dtCurr.Subtract(origData.dtEve); PlantLogModel answ = new PlantLogModel() { FluxType = origData.flux, ValNumber = valDbl, ValString = origData.valore, PlantId = plantId, DtEvent = DateTime.Now.Subtract(delta) }; return answ; } public async Task DbForceMigrate() { return await Task.FromResult(dbController.DbForceMigrate()); } public void Dispose() { // Clear database controller dbController.Dispose(); } public async Task HasPlantLog() { return await Task.FromResult(dbController.HasPlantLog()); } /// /// invalida tutta la cache in caso di update /// /// public async Task InvalidateAllCache() { await distributedCache.RemoveAsync("DATA:CONFIG"); await distributedCache.RemoveAsync("DATA:CHECKLEVEL"); await distributedCache.RemoveAsync("DATA:PLANTS:ListDTO"); await distributedCache.RemoveAsync("DATA:SUPPL:List"); await distributedCache.RemoveAsync("DATA:TRANSP:List"); await distributedCache.RemoveAsync("DATA:WEEKPLAN:List"); } public async Task> ItemsGetAll() { //return Task.FromResult(dbController.ActionsGetAll()); List dbResult = new List(); string cacheKey = "DATA:ITEMS"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetItems(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per ItemsGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } /// /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato /// /// /// public async Task> mTaskMacchina(string idxMacchina) { // hard coded dimensione vettore DatiMacchine Dictionary answ = new Dictionary(); // ORA recupero da memoria redis... try { string cacheKey = exeTaskHash(idxMacchina); string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); answ = JsonConvert.DeserializeObject>(rawData); } } catch (Exception exc) { Log.Info($"Errore in recupero dati EXE TASK x Redis mTaskMacchina - idxMacchina {idxMacchina}{Environment.NewLine}{exc}"); } return answ; } public async Task OrderDelete(OrderModel currItem) { bool done = false; try { done = dbController.OrderDelete(currItem); InvalidateAllCache(); } catch (Exception exc) { Log.Error($"Eccezione in OrderDelete:{Environment.NewLine}{exc}"); } return await Task.FromResult(done); } public async Task OrderGetByCode(string OrderCode) { OrderModel dbResult = new OrderModel(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetOrderByCode(OrderCode); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per OrderGetByCode: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public async Task OrderGetById(int OrderId) { OrderModel dbResult = new OrderModel(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetOrderById(OrderId); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per OrderGetById: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public async Task> OrdersGetFilt(SelectOrderData CurrFilter) { List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetOrdersFilt(CurrFilter.PlantId, CurrFilter.SupplierId, CurrFilter.TransporterId, CurrFilter.DateStart, CurrFilter.DateEnd, CurrFilter.ShowClosed); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per OrdersGetFilt: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } /// /// Elenco degli ordini ancora aperti x il Plant /// /// /// public async Task> OrdersGetOpen(int PlantId) { List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetOrdersOpen(PlantId); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per OrdersGetOpen | PlantId: {PlantId} | {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public async Task OrderUpdate(OrderModel currItem) { bool done = false; try { done = dbController.OrderUpdate(currItem); InvalidateAllCache(); } catch (Exception exc) { Log.Error($"Eccezione in OrderUpdate:{Environment.NewLine}{exc}"); } return await Task.FromResult(done); } public async Task> PlantLogGetFilt(int PlantId, DateTime DtMaxDate, int numRec) { List dbResult = new List(); string cacheKey = $"DATA:PLANTS:LOGS:{PlantId}:{DtMaxDate:yyyyMMddHHmm}:{numRec}"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetPlantLog(PlantId, DtMaxDate, numRec); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per PlantLogGetFilt: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public async Task PlantLogInsert(List newItems) { bool fatto = false; // init valori int IntervalMin = 60; int.TryParse(_configuration["IntervalMin"], out IntervalMin); List item2insert = new List(); int PlantId = newItems.FirstOrDefault().PlantId; // aggiorno valori ACT x DTO await updateCurrDTO(newItems); // recupero ultimi inseriti List lastValues = PlantLogGetLastByFlux(PlantId).Result; // verifico i flussi presenti tra quelli ricevuti List fluxList = newItems .GroupBy(g => g.FluxType) .Select(s => s.First().FluxType) .ToList(); foreach (var item in fluxList) { // cerco se c'è valore... var lastInserted = lastValues.Where(x => x.FluxType == item).FirstOrDefault(); DateTime dateLimit = DateTime.Today.AddDays(-1); if (lastInserted != null) { // per ogni flusso calcolo il valore minimo x inserimento (arrotondando a minInt) dateLimit = dbController.DateRoundEnd(lastInserted.DtEvent, IntervalMin); } // cerco se ho record > valore minimo x ogni flusso ricevuto List insCandidates = newItems.Where(x => x.FluxType == item && x.DtEvent >= dateLimit).OrderBy(x => x.DtEvent).ToList(); int num2ins = insCandidates.Count; while (num2ins > 0) { var newRec = insCandidates.First(); // il primo lo accodo da inserire item2insert.Add(newRec); // calcolo nuovo veto dateLimit = dbController.DateRoundEnd(newRec.DtEvent, IntervalMin); // ...e se ho record > data limite accodo insCandidates = newItems.Where(x => x.FluxType == item && x.DtEvent > dateLimit).OrderBy(x => x.DtEvent).ToList(); num2ins = insCandidates.Count; } } // se ho record da inserire... if (item2insert.Count > 0) { // faccio vero insert fatto = dbController.PlantLogInsertNew(item2insert); // invalido i vari valori in cache await distributedCache.RemoveAsync($"DATA:PLANTS:LastFlux:{PlantId}"); await distributedCache.RemoveAsync($"DATA:PLANTS:ListDTO"); Log.Trace($"PlantLogInsert | PlantId: {PlantId} | Completato insert {item2insert.Count} rec"); } // restituisco return await Task.FromResult(fatto); } public async Task> PlantsAnalisysGetByCode(SelectOrderData CurrFilter) { List dbResult = new List(); string cacheKey = $"DATA:PLANTS:LevelSum:{CurrFilter.PlantId}:{CurrFilter.DateStart:yyMMdd}:{CurrFilter.DateEnd:yyMMdd}"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetPlantLogSummary(CurrFilter.PlantId, CurrFilter.DateStart, CurrFilter.DateEnd); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per PlantsAnalisysGetByCode: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public async Task PlantsAnalisysReset(SelectOrderData CurrFilter) { bool answ = false; string cacheKey = $"DATA:PLANTS:LevelSum:{CurrFilter.PlantId}:{CurrFilter.DateStart:yyMMdd}:{CurrFilter.DateEnd:yyMMdd}"; await distributedCache.RemoveAsync(cacheKey); answ = true; return await Task.FromResult(answ); } public async Task> PlantsGetAll() { List dbResult = new List(); string cacheKey = "DATA:PLANTS:ListDTO"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); int maxRec = 100; int.TryParse(_configuration["MaxLogRecord"], out maxRec); dbResult = dbController.GetPlantsDTO(maxRec); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per PlantsGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public async Task PlantsGetByCode(string PlantCode) { PlantDTO answ = new PlantDTO(); var ListRecords = await PlantsGetAll(); var found = ListRecords.Where(x => x.PlantCode == PlantCode).FirstOrDefault(); if (found != null) { answ = found; } return await Task.FromResult(answ); } public async Task PlantUpdate(PlantDTO currItem) { bool done = false; try { done = dbController.PlantUpdate(currItem); InvalidateAllCache(); } catch (Exception exc) { Log.Error($"Eccezione in OrderUpdate:{Environment.NewLine}{exc}"); } return await Task.FromResult(done); } public void RebootLogInsert(RebootLogModel newItem) { try { dbController.RecordRebootLog(newItem); } catch { } } public void rollBackEdit(object item) { dbController.rollBackEntity(item); } public async Task> SuppliersGetAll() { List dbResult = new List(); string cacheKey = "DATA:SUPPL:List"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetSuppliers(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per PlantsGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public async Task> TransportersGetAll() { List dbResult = new List(); string cacheKey = $"DATA:TRANSP:List"; string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetTransporters(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per PlantsGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public async Task> UsersGetFilt(UserLevel UsrLvl, int PlantId, int SupplierId, int TransporterId) { List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetUsersFilt(UsrLvl, PlantId, SupplierId, TransporterId); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per UsersGetFilt: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public void UserUpdate(UserModel currItem) { try { dbController.UserUpdate(currItem); } catch { } } public async void WeekPlanDelete(WeekPlanModel currItem) { try { //dbController.ResetController(); dbController.WeekPlanDelete(currItem); string cacheKey = $"DATA:WEEKPLAN:List"; await distributedCache.RemoveAsync(cacheKey); } catch { } } public async Task> WeekPlanGet() { List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetWeekPlan(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per WeekPlanGet: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public async void WeekPlanUpdate(WeekPlanModel currItem) { try { //dbController.ResetController(); dbController.WeekPlanUpdate(currItem); string cacheKey = $"DATA:WEEKPLAN:List"; await distributedCache.RemoveAsync(cacheKey); } catch { } } #endregion Public Methods } }