Оптимизация запроса получения ГГД

This commit is contained in:
Степанов Дмитрий 2024-03-29 07:30:19 +03:00
parent 2ad59e1af2
commit ea9e90dea3
3 changed files with 41 additions and 46 deletions

View File

@ -1 +0,0 @@


View File

@ -52,12 +52,6 @@ namespace AsbCloudDb.Model
[Column("comment"), Comment("Комментарий")]
public string? Comment { get; set; }
[NotMapped]
public double NptHours { get; set; }
[NotMapped]
public double Day { get; set; }
[JsonIgnore]
[ForeignKey(nameof(IdWell))]
public virtual Well Well { get; set; } = null!;

View File

@ -55,9 +55,7 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationDto, Well
var entities = await query.AsNoTracking()
.ToArrayAsync(token);
var dtos = entities.Select(Convert);
return dtos;
return await ConvertWithDrillingDaysAndNpvHoursAsync(entities, token);
}
public async Task<PaginationContainer<WellOperationDto>> GetPageAsync(WellOperationRequest request, CancellationToken token)
@ -67,7 +65,7 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationDto, Well
var query = BuildQuery(request);
var entites = await query.Skip(skip)
var entities = await query.Skip(skip)
.Take(take)
.AsNoTracking()
.ToArrayAsync(token);
@ -77,7 +75,7 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationDto, Well
Skip = skip,
Take = take,
Count = await query.CountAsync(token),
Items = entites.Select(Convert)
Items = await ConvertWithDrillingDaysAndNpvHoursAsync(entities, token)
};
return paginationContainer;
@ -182,43 +180,10 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationDto, Well
private IQueryable<WellOperation> BuildQuery(WellOperationRequest request)
{
var currentWellOperations = GetQuery()
.Where(e => request.IdsWell != null && request.IdsWell.Contains(e.IdWell));
var query = GetQuery()
.Where(e => request.IdsWell != null && request.IdsWell.Contains(e.IdWell))
.OrderBy(e => e.DateStart)
.Select(o => new WellOperation
{
Id = o.Id,
IdPlan = o.IdPlan,
IdType = o.IdType,
IdWell = o.IdWell,
LastUpdateDate = o.LastUpdateDate,
IdWellSectionType = o.IdWellSectionType,
IdCategory = o.IdCategory,
OperationCategory = o.OperationCategory,
WellSectionType = o.WellSectionType,
DateStart = o.DateStart,
DepthStart = o.DepthStart,
DepthEnd = o.DepthEnd,
DurationHours = o.DurationHours,
CategoryInfo = o.CategoryInfo,
Comment = o.Comment,
IdUser = o.IdUser,
NptHours = currentWellOperations
.Where(e => e.IdType == 1 && e.IdWell == o.IdWell)
.Where(e => WellOperationCategory.NonProductiveTimeSubIds.Contains(e.IdCategory))
.Select(e => e.DurationHours)
.Sum(),
Day = (o.DateStart - currentWellOperations
.Where(subOp => subOp.IdType == o.IdType && subOp.IdWell == o.IdWell)
.Where(subOp => subOp.DateStart <= o.DateStart)
.Min(subOp => subOp.DateStart))
.TotalDays
});
.AsQueryable();
if (request.OperationType.HasValue)
query = query.Where(e => e.IdType == request.OperationType.Value);
@ -341,6 +306,43 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationDto, Well
};
}
private async Task<IEnumerable<WellOperationDto>> ConvertWithDrillingDaysAndNpvHoursAsync(IEnumerable<WellOperation> entities,
CancellationToken token)
{
var idsWell = entities.Select(e => e.IdWell).Distinct();
var currentWellOperations = GetQuery()
.Where(entity => idsWell.Contains(entity.IdWell));
var dateFirstDrillingOperationByIdWell = await currentWellOperations
.Where(entity => entity.IdType == WellOperation.IdOperationTypeFact)
.GroupBy(entity => entity.IdWell)
.ToDictionaryAsync(g => g.Key, g => g.Min(o => o.DateStart), token);
var operationsWithNptByIdWell = await currentWellOperations.Where(entity =>
entity.IdType == WellOperation.IdOperationTypeFact &&
WellOperationCategory.NonProductiveTimeSubIds.Contains(entity.IdCategory))
.GroupBy(entity => entity.IdWell)
.ToDictionaryAsync(g => g.Key, g => g.Select(o => o), token);
var dtos = entities.Select(entity =>
{
var dto = Convert(entity);
if (dateFirstDrillingOperationByIdWell.TryGetValue(entity.IdWell, out var dateFirstDrillingOperation))
dto.Day = (entity.DateStart - dateFirstDrillingOperation).TotalDays;
if (operationsWithNptByIdWell.TryGetValue(entity.IdWell, out var wellOperationsWithNtp))
dto.NptHours = wellOperationsWithNtp
.Where(o => o.DateStart <= entity.DateStart)
.Sum(e => e.DurationHours);
return dto;
});
return dtos;
}
protected override WellOperation Convert(WellOperationDto src)
{
var entity = src.Adapt<WellOperation>();