From 40860c05632cac35e9dfee267833957eba3cd016 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Wed, 8 May 2024 10:47:31 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A5=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B2=D0=BE=D0=B9=20=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B5=D0=B9=20=D0=BE=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B2=20=D0=BA=D0=B5?= =?UTF-8?q?=D1=88=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IWellOperationRepository.cs | 53 ++++++++------- .../Repository/DepositRepository.cs | 11 ++-- .../Repository/WellOperationRepository.cs | 66 ++++++++++++++++++- .../Services/WellService.cs | 25 ++++--- 4 files changed, 111 insertions(+), 44 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index d37a1e90..12246578 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -1,9 +1,9 @@ using AsbCloudApp.Data; +using AsbCloudApp.Data.WellOperation; +using AsbCloudApp.Requests; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using AsbCloudApp.Data.WellOperation; -using AsbCloudApp.Requests; namespace AsbCloudApp.Repositories { @@ -17,8 +17,8 @@ namespace AsbCloudApp.Repositories /// /// IEnumerable GetSectionTypes(); - - /// + + /// /// Получить страницу списка операций /// /// @@ -26,7 +26,7 @@ namespace AsbCloudApp.Repositories /// Task> GetAsync(WellOperationRequest request, CancellationToken token); - /// + /// /// Получить страницу списка операций /// /// @@ -34,7 +34,7 @@ namespace AsbCloudApp.Repositories /// Task> GetPageAsync(WellOperationRequest request, CancellationToken token); - /// + /// /// Получить статистику операции по скважине с группировкой по категориям /// /// @@ -42,14 +42,14 @@ namespace AsbCloudApp.Repositories /// Task> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token); - /// - /// Добавить несколько операций - /// - /// - /// - /// - /// - Task InsertRangeAsync(IEnumerable dtos, bool deleteBeforeInsert, CancellationToken token); + /// + /// Добавить несколько операций + /// + /// + /// + /// + /// + Task InsertRangeAsync(IEnumerable dtos, bool deleteBeforeInsert, CancellationToken token); /// /// Обновить существующую операцию @@ -75,13 +75,20 @@ namespace AsbCloudApp.Repositories /// Task> GetSectionsAsync(IEnumerable idsWells, CancellationToken token); - /// - /// Получить диапазон дат выполнения операций - /// - /// - /// - /// - /// - Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken); - } + /// + /// Получить диапазон дат выполнения операций + /// + /// + /// + /// + /// + Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken); + + /// + /// Возвращает первую и последнюю фактическую операцию + /// + /// + /// + (WellOperationDto First, WellOperationDto Last)? GetFirstAndLastFact(int idWell); + } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/DepositRepository.cs b/AsbCloudInfrastructure/Repository/DepositRepository.cs index 804d130e..f7bc4fdd 100644 --- a/AsbCloudInfrastructure/Repository/DepositRepository.cs +++ b/AsbCloudInfrastructure/Repository/DepositRepository.cs @@ -16,12 +16,12 @@ namespace AsbCloudInfrastructure.Repository public class DepositRepository : IDepositRepository { private readonly IAsbCloudDbContext db; - private readonly IWellService wellService; + private readonly ITelemetryService telemetryService; - public DepositRepository(IAsbCloudDbContext db, IWellService wellService) + public DepositRepository(IAsbCloudDbContext db, ITelemetryService telemetryService) { this.db = db; - this.wellService = wellService; + this.telemetryService = telemetryService; } /// @@ -112,8 +112,9 @@ namespace AsbCloudInfrastructure.Repository { var dto = well.Adapt(); dto.WellType = well.WellType.Caption; - dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id) - .ToOffset(TimeSpan.FromHours(well.Timezone.Hours)); + dto.LastTelemetryDate = well.IdTelemetry != null + ? telemetryService.GetDatesRange(well.IdTelemetry.Value).To.ToOffset(TimeSpan.FromHours(well.Timezone.Hours)) + : DateTimeOffset.MinValue; dto.Cluster = gCluster.Key.Caption; dto.Deposit = gDeposit.Key.Caption; return dto; diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 522895a7..95905314 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -20,6 +20,7 @@ namespace AsbCloudInfrastructure.Repository; public class WellOperationRepository : CrudRepositoryBase, IWellOperationRepository { + private const string cacheKeyWellOperations = "FirstAndLastFactWellsOperations"; private readonly IMemoryCache memoryCache; private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; private readonly IWellService wellService; @@ -148,14 +149,26 @@ public class WellOperationRepository : CrudRepositoryBase 0) + memoryCache.Remove(cacheKeyWellOperations); + + return result; + } - public override Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token) + public override async Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token) { EnsureValidWellOperations(dtos); - return base.UpdateRangeAsync(dtos, token); + var result = await base.UpdateRangeAsync(dtos, token); + + if (result > 0) + memoryCache.Remove(cacheKeyWellOperations); + + return result; + } private static void EnsureValidWellOperations(IEnumerable dtos) @@ -350,6 +363,53 @@ public class WellOperationRepository : CrudRepositoryBase + { + entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); + var query = dbContext.Set() + .Where(o => o.IdType == WellOperation.IdOperationTypeFact) + .GroupBy(o => o.IdWell) + .Select(group => new + { + IdWell = group.Key, + FirstFact = group.OrderBy(o => o.DateStart).First(), + LastFact = group.OrderBy(o => o.DateStart).Last(), + }); + + var entities = query.ToArray(); + + var dictionary = entities.ToDictionary(s => s.IdWell, s => (Convert(s.FirstFact), Convert(s.LastFact))); + entry.Value = dictionary; + + return dictionary; + + })!; + + var firstAndLast = cachedDictionary.GetValueOrDefault(idWell); + return firstAndLast; + + } + + public override async Task DeleteAsync(int id, CancellationToken token) + { + var result = await base.DeleteAsync(id, token); + if (result > 0) + memoryCache.Remove(cacheKeyWellOperations); + + return result; + } + + public override async Task DeleteRangeAsync(IEnumerable ids, CancellationToken token) + { + var result = await base.DeleteRangeAsync(ids, token); + if (result > 0) + memoryCache.Remove(cacheKeyWellOperations); + + return result; + } + protected override WellOperation Convert(WellOperationDto src) { var entity = src.Adapt(); diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index a10ff824..2c361e38 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -116,12 +116,12 @@ namespace AsbCloudInfrastructure.Services if (well is null) return null; - + var wellInfo = wellInfoService.FirstOrDefault(well => well.Id == idWell); if (wellInfo is null) return well.Adapt(); - + wellInfo.IdState = well.IdState; return wellInfo; } @@ -153,7 +153,7 @@ namespace AsbCloudInfrastructure.Services { if (IsTelemetryAssignedToDifferentWell(dto)) throw new ArgumentInvalidException(nameof(dto), "Телеметрия уже была привязана к другой скважине."); - + if (dto.Id != 0 && (await GetCacheAsync(token)).Any(w => w.Id == dto.Id)) throw new ArgumentInvalidException(nameof(dto), $"Нельзя повторно добавить скважину с id: {dto.Id}"); @@ -177,12 +177,12 @@ namespace AsbCloudInfrastructure.Services throw new NotImplementedException(); } - public override async Task UpdateAsync(WellDto dto, + public override async Task UpdateAsync(WellDto dto, CancellationToken token) { if (IsTelemetryAssignedToDifferentWell(dto)) throw new ArgumentInvalidException(nameof(dto), "Телеметрия уже была привязана к другой скважине."); - + var oldRelations = (await GetCacheRelationCompanyWellAsync(token)) .Where(r => r.IdWell == dto.Id).ToArray(); @@ -192,16 +192,16 @@ namespace AsbCloudInfrastructure.Services dbContext.RelationCompaniesWells .RemoveRange(dbContext.RelationCompaniesWells .Where(r => r.IdWell == dto.Id)); - + DropCacheRelationCompanyWell(); var newRelations = dto.Companies .Select(c => new RelationCompanyWell { - IdWell = dto.Id, + IdWell = dto.Id, IdCompany = c.Id }); - + dbContext.RelationCompaniesWells.AddRange(newRelations); } @@ -215,7 +215,7 @@ namespace AsbCloudInfrastructure.Services public async Task GetWellCaptionByIdAsync(int idWell, CancellationToken token) { - var entity = await GetOrDefaultAsync(idWell, token).ConfigureAwait(false); + var entity = await GetOrDefaultAsync(idWell, token).ConfigureAwait(false); return entity!.Caption; } @@ -272,10 +272,9 @@ namespace AsbCloudInfrastructure.Services if (entity.Timezone is null) dto.Timezone = GetTimezone(entity.Id); - - dto.StartDate = dbContext.WellOperations.Where(e => e.IdType == WellOperation.IdOperationTypeFact) - .AsNoTracking() - .MinOrDefault(e => e.DateStart)?.ToRemoteDateTime(dto.Timezone.Hours); + + dto.StartDate = wellOperationRepository + .GetFirstAndLastFact(entity.Id)?.First?.DateStart; dto.WellType = entity.WellType.Caption; dto.Cluster = entity.Cluster.Caption; dto.Deposit = entity.Cluster.Deposit.Caption;