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 StatsAggrRepository : BaseRepository, IStatsAggrRepository { #region Public Constructors public StatsAggrRepository(IDbContextFactory ctxFactory) : base(ctxFactory) { } #endregion Public Constructors #region Public Methods /// public async Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd) { await using var dbCtx = await CreateContextAsync(); return await dbCtx .DbSetStatsAggr .Where(x => x.Hour >= dtStart && x.Hour <= dtEnd) .AsNoTracking() .OrderBy(x => x.Hour) .ToListAsync(); } /// public async Task GetRangeAsync() { await using var dbCtx = await CreateContextAsync(); DtUtils.Periodo answ = new DtUtils.Periodo(DtUtils.PeriodSet.Today); var query = dbCtx.DbSetStatsAggr.AsQueryable(); var minHour = await query.MinAsync(x => x.Hour); var maxHour = await query.MaxAsync(x => x.Hour); answ.Inizio = minHour; answ.Fine = maxHour; // ritorno! 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 .DbSetStatsAggr .Where(x => x.Hour >= startDate && x.Hour <= endDate) .ExecuteDeleteAsync(); #endif var items = await dbCtx.DbSetStatsAggr .Where(x => x.Hour >= startDate && x.Hour <= endDate) .ToListAsync(); dbCtx.DbSetStatsAggr.RemoveRange(items); await dbCtx.SaveChangesAsync(); } } // ora preparo inserimento massivo var existingRecords = await dbCtx .DbSetStatsAggr .Where(x => listRecords.Select(r => r.Hour).Contains(x.Hour) && listRecords.Select(r => r.Destination).Contains(x.Destination)) .ToListAsync(); if (existingRecords.Count > 0) { var existingHours = existingRecords.Select(r => new { r.Hour, r.Destination }).ToHashSet(); var recordsToUpdate = listRecords.Where(r => existingHours.Contains(new { Hour = r.Hour, Destination = r.Destination })).ToList(); var recordsToAdd = listRecords.Where(r => !existingHours.Contains(new { Hour = r.Hour, Destination = r.Destination })).ToList(); foreach (var updateRec in recordsToUpdate) { var existing = existingRecords.First(x => x.Hour == updateRec.Hour && x.Destination == updateRec.Destination); 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.DbSetStatsAggr.AddRangeAsync(recordsToAdd); } } else { await dbCtx .DbSetStatsAggr .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 Public Methods } }