using EgwCoreLib.Utils; using Microsoft.EntityFrameworkCore; using MP.Data.DbModels.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace MP.Data.Repository.Utils { public class StatsDetailRepository : BaseRepository, IStatsDetailRepository { #region Public Constructors public StatsDetailRepository(IDbContextFactory ctxFactory) : base(ctxFactory) { } #endregion Public Constructors #region Internal Methods /// public async Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "") { await using var dbCtx = await CreateContextAsync(); List answ = new List(); // recupero ed ordino per data-ora var query = dbCtx.DbSetStatsDet .Where(x => x.Hour >= dtStart && x.Hour <= dtEnd); if (!string.IsNullOrEmpty(sEnvir)) query = query.Where(x => x.Destination == sEnvir); if (!string.IsNullOrEmpty(sType)) query = query.Where(x => x.Type == sType); answ = await query .AsNoTracking() .OrderBy(x => x.Hour) .ThenBy(x => x.Destination) .ThenBy(x => x.Type) .ToListAsync(); return answ; } /// public async Task GetRangeAsync(string sEnvir, string sType) { await using var dbCtx = await CreateContextAsync(); DtUtils.Periodo answ = new DtUtils.Periodo(DtUtils.PeriodSet.Today); var query = dbCtx.DbSetStatsDet.AsQueryable(); if (!string.IsNullOrEmpty(sEnvir)) query = query.Where(x => x.Destination == sEnvir); if (!string.IsNullOrEmpty(sType)) query = query.Where(x => x.Type == sType); var minHour = await query.MinAsync(x => x.Hour); var maxHour = await query.MaxAsync(x => x.Hour); answ.Inizio = minHour; answ.Fine = maxHour; return answ; } /// public async Task UpsertManyAsync(List listRecords, bool removeOld) { int answ = 0; await using var dbCtx = await CreateContextAsync(); await using var tx = await dbCtx.Database.BeginTransactionAsync(); try { // in primis se richiesto calcolo range periodo e svuoto... if (removeOld) { var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault(); var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault(); if (firstRec != null && lastRec != null) { DateTime startDate = firstRec.Hour; DateTime endDate = lastRec.Hour; // uso direttamente ExecuteDelete quando in EFCore8... #if false await dbCtx .DbSetStatsDet .Where(x => x.Hour >= startDate && x.Hour <= endDate) .ExecuteDeleteAsync(); #endif var items = await dbCtx.DbSetStatsDet .Where(x => x.Hour >= startDate && x.Hour <= endDate) .ToListAsync(); dbCtx.DbSetStatsDet.RemoveRange(items); await dbCtx.SaveChangesAsync(); } } // ora preparo inserimento massivo var existingRecords = await dbCtx .DbSetStatsDet .Where(x => listRecords.Select(r => new { r.Hour, r.Destination, r.Type }).Contains(new { Hour = x.Hour, Destination = x.Destination, Type = x.Type })) .ToListAsync(); if (existingRecords.Count > 0) { var existingKeys = existingRecords.Select(r => new { r.Hour, r.Destination, r.Type }).ToHashSet(); var recordsToUpdate = listRecords.Where(r => existingKeys.Contains(new { Hour = r.Hour, Destination = r.Destination, Type = r.Type })).ToList(); var recordsToAdd = listRecords.Where(r => !existingKeys.Contains(new { Hour = r.Hour, Destination = r.Destination, Type = r.Type })).ToList(); foreach (var updateRec in recordsToUpdate) { var existing = Enumerable.First((IEnumerable)existingRecords, (Func)(x => x.Hour == updateRec.Hour && x.Destination == updateRec.Destination && x.Type == updateRec.Type)); existing.RequestCount = updateRec.RequestCount; existing.AvgDuration = updateRec.AvgDuration; existing.MaxDuration = updateRec.MaxDuration; existing.MinDuration = updateRec.MinDuration; existing.NoReply = updateRec.NoReply; } if (recordsToAdd.Count > 0) { await dbCtx.DbSetStatsDet.AddRangeAsync(recordsToAdd); } } else { await dbCtx .DbSetStatsDet .AddRangeAsync(listRecords); } // salvo! answ = await dbCtx.SaveChangesAsync(); // commit transazione await tx.CommitAsync(); // libero memoria del changeTracker dbCtx.ChangeTracker.Clear(); return answ; } catch { await tx.RollbackAsync(); throw; } } #endregion Internal Methods } }