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;