using AsbCloudDb.Model; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Background.PeriodicWorks { internal class WorkProcessMapDrillingCashe : Work { private int MechanicalDrillingCategoryId = 4001; public WorkProcessMapDrillingCashe() : base("Generate process map drilling cache table") { Timeout = TimeSpan.FromMinutes(1); } protected override Task Action(string id, IServiceProvider services, Action onProgressCallback, CancellationToken token) { //1 найти последнюю запись в кеш-таблице (по полям "Дата до") //2 определяем дату с которой начинаем анализ //3 находим автоопределнные операции по скважине, начиная с начальной даты из пункта 2 // 3.1 только те, которые связанные с бурением (idParent = 4001) // 3.2 выбираем 500 операций // 3.3. выбираем минимальную дату начала и максимальную дату окончания //4 по полученным в пункте выше данным выбираем записи из telemetry_data_saub // 4.1.выбираем те у которых (bit_depth == well_depth) //5. для каждой операции из 3.2 находим соответствующий ей кусок телеметрии (по дате начала и окончания) // и храним индексы этого куска в виде span //6. кусок телеметрии, полученный в пункте 5 (span) и соответствующая ей операция направляется на разбивку диапазонов //7/ разбивка диапазонов: // параметры метода: массив из var dateStart = DateTimeOffset.UtcNow.AddDays(-3500); using var db = services.GetRequiredService(); //а остальные операции, которые не вошли в 500 первых? var detectedOperations = db.DetectedOperations .Where(o => o.DateStart > dateStart) .Where(o => o.OperationCategory.IdParent == MechanicalDrillingCategoryId) .Take(500) .ToArray(); var minDate = detectedOperations.Min(o => o.DateStart); var maxDate = detectedOperations.Max(o => o.DateEnd); var telemetryDataSaub = db.TelemetryDataSaub .Where(t => t.DateTime >= minDate) .Where(t => t.DateTime <= maxDate) .Where(t => t.BitDepth == t.WellDepth) .OrderBy(t => t.DateTime) .ToArray(); var result = new List(); foreach (var operation in detectedOperations) { var indexStart = 0; var length = 0; foreach (var telemetryDataSaubItem in telemetryDataSaub) { if(operation.DateStart <= telemetryDataSaubItem.DateTime && operation.DateEnd >= telemetryDataSaubItem.DateTime) { length++; } else if(length > 0) { var subset = telemetryDataSaub.AsSpan(indexStart, length); var ranges = getRanges(subset, operation); result.AddRange(ranges); break; } indexStart++; } } return null; } private List getRanges(Span span, DetectedOperation operation) { var result = new List(); var cacheItem = new CacheItem(); cacheItem.Elems.Add(span[0]); result.Add(cacheItem); for (var i=1; i Elems = new List(); } }