diff --git a/MP-TAB3.sln b/MP-TAB3.sln
index 5e287c2d..f8d3b2c8 100644
--- a/MP-TAB3.sln
+++ b/MP-TAB3.sln
@@ -10,7 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP-TAB-SERV", "MP-TAB-SERV\MP-TAB-SERV.csproj", "{E7A7C262-7807-4503-949D-5A6FE3DF4400}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP-TAB-SERV", "MP-TAB-SERV\MP-TAB-SERV.csproj", "{E7A7C262-7807-4503-949D-5A6FE3DF4400}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/MP.Data/Controllers/MpTabController.cs b/MP.Data/Controllers/MpTabController.cs
new file mode 100644
index 00000000..1f6690fd
--- /dev/null
+++ b/MP.Data/Controllers/MpTabController.cs
@@ -0,0 +1,58 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using MP.Data.DatabaseModels;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace MP.Data.Controllers
+{
+ public class MpTabController : IDisposable
+ {
+ #region Public Constructors
+
+ public MpTabController(IConfiguration configuration)
+ {
+ _configuration = configuration;
+ Log.Info("Avviata classe MpTabController");
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ public void Dispose()
+ {
+ _configuration = null;
+ }
+
+ ///
+ /// Restituisce l'anagrafica eventi per intero
+ ///
+ ///
+ public List AnagEventiGetAll()
+ {
+ List dbResult = new List();
+ using (var dbCtx = new MoonProContext(_configuration))
+ {
+ dbResult = dbCtx
+ .DbSetAnagEventi
+ .AsNoTracking()
+ .ToList();
+ }
+ return dbResult;
+ }
+
+ #endregion Public Methods
+
+ #region Private Fields
+
+ private static IConfiguration _configuration;
+
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ #endregion Private Fields
+ }
+}
\ No newline at end of file
diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs
new file mode 100644
index 00000000..f4f4b950
--- /dev/null
+++ b/MP.Data/Services/TabDataService.cs
@@ -0,0 +1,141 @@
+using Microsoft.Extensions.Configuration;
+using MP.Data.DatabaseModels;
+using Newtonsoft.Json;
+using NLog.Fluent;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MP.Data.Services
+{
+ public class TabDataService
+ {
+ #region Public Constructors
+
+ public TabDataService(IConfiguration configuration)
+ {
+ _configuration = configuration;
+
+ // setup compoenti REDIS
+ redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
+ redisDb = redisConn.GetDatabase();
+
+ // conf DB
+ string connStr = _configuration.GetConnectionString("Mp.All");
+ if (string.IsNullOrEmpty(connStr))
+ {
+ Log.Error("ConnString empty!");
+ }
+ else
+ {
+ dbController = new Controllers.MpTabController(configuration);
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine($"TabDataService | MpSpecController OK");
+ Log.Info(sb.ToString());
+ }
+ }
+
+ #endregion Public Constructors
+
+ protected static IConfiguration _configuration = null!;
+
+ public static Controllers.MpTabController dbController { get; set; } = null!;
+
+ public async Task> AnagEventiGetAll()
+ {
+ // setup parametri costanti
+ bool inCorso = false;
+ string keyRichPart = "*";
+ string Reparto = "*";
+ DateTime startDate = new DateTime(2000, 1, 1);
+ DateTime endDate = DateTime.Today.AddDays(1);
+ string source = "DB";
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
+ List? result = new List();
+ // cerco in redis...
+ string currKey = $"{redisBaseKey}:AnagEventi";
+ RedisValue rawData = await redisDb.StringGetAsync(currKey);
+ if (!string.IsNullOrEmpty($"{rawData}"))
+ {
+ result = JsonConvert.DeserializeObject>($"{rawData}");
+ source = "REDIS";
+ }
+ else
+ {
+ result = dbController.AnagEventiGetAll();
+ // serializzp e salvo...
+ rawData = JsonConvert.SerializeObject(result);
+ await redisDb.StringSetAsync(currKey, rawData, LongCache);
+ }
+ if (result == null)
+ {
+ result = new List();
+ }
+ sw.Stop();
+ return result;
+ }
+ #region Protected Properties
+
+ ///
+ /// Durata cache breve (1 min circa + perturbazione percentuale +/-10%)
+ ///
+ protected TimeSpan FastCache
+ {
+ get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
+ }
+
+ ///
+ /// Durata cache lunga (+ perturbazione percentuale +/-10%)
+ ///
+ protected TimeSpan LongCache
+ {
+ get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
+ }
+
+ ///
+ /// Durata cache MOLTO breve (10 sec circa + perturbazione percentuale +/-10%)
+ ///
+ protected TimeSpan UltraFastCache
+ {
+ get => TimeSpan.FromSeconds(cacheTtlShort / 6 * rnd.Next(900, 1100) / 1000);
+ }
+
+ ///
+ /// Durata cache MOLTO lunga (+ perturbazione percentuale +/-10%)
+ ///
+ protected TimeSpan UltraLongCache
+ {
+ get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
+ }
+
+ #endregion Protected Properties
+ #region Private Fields
+
+ ///
+ /// Oggetto per connessione a REDIS
+ ///
+ protected ConnectionMultiplexer redisConn = null!;
+
+ ///
+ /// Oggetto DB redis da impiegare x chiamate R/W
+ ///
+ protected IDatabase redisDb = null!;
+
+ ///
+ /// Durata cache lunga IN SECONDI
+ ///
+ private int cacheTtlLong = 60 * 5;
+ ///
+ /// Durata cache breve IN SECONDI
+ ///
+ private int cacheTtlShort = 60 * 1;
+
+ private string redisBaseKey = "MP:TAB:Cache";
+ private Random rnd = new Random();
+ #endregion Private Fields
+ }
+}
\ No newline at end of file