From 7c827f4faebdccb8eb3f01c41f8a75d23d0cb9c9 Mon Sep 17 00:00:00 2001 From: eugeniy_ivanov Date: Tue, 11 Apr 2023 00:32:06 +0500 Subject: [PATCH] rework get method in rep --- AsbCloudApp/Repositories/IGtrRepository.cs | 2 +- AsbCloudInfrastructure/DependencyInjection.cs | 4 +- .../Repository/GtrWitsRepository.cs | 312 ++++++++++++------ .../Controllers/GTR/GtrWitsController.cs | 48 +-- 4 files changed, 243 insertions(+), 123 deletions(-) diff --git a/AsbCloudApp/Repositories/IGtrRepository.cs b/AsbCloudApp/Repositories/IGtrRepository.cs index 587a78a0..d982c373 100644 --- a/AsbCloudApp/Repositories/IGtrRepository.cs +++ b/AsbCloudApp/Repositories/IGtrRepository.cs @@ -11,7 +11,7 @@ namespace AsbCloudApp.Repositories /// /// данные ГТИ /// - public interface IGtrRepository + public interface IGtrRepository { /// /// добавить данные (для панели бурильщика) diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 39ef6353..b2310ae5 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -138,9 +138,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient, GtrWitsRepository>(); - services.AddTransient, GtrWitsRepository>(); - services.AddTransient, GtrWitsRepository>(); + services.AddTransient(); // admin crud services: services.AddTransient, CrudCacheRepositoryBase>(s => diff --git a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs index a603c5a6..ffa39c9c 100644 --- a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs +++ b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs @@ -13,19 +13,19 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Repository { #nullable enable - public class GtrWitsRepository : IGtrRepository - where TEntity : WitsItemBase + public class GtrWitsRepository : IGtrRepository + { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; - private readonly DbSet dbset; + private static Random random = new Random((int)(DateTime.Now.Ticks % 0xFFFFFFFF)); public GtrWitsRepository( IAsbCloudDbContext db, ITelemetryService telemetryService) { - dbset = db.Set(); + this.db = db; this.telemetryService = telemetryService; } @@ -60,42 +60,98 @@ namespace AsbCloudInfrastructure.Repository // return cacheData; var dateEnd = dateBeginUtc.AddSeconds(intervalSec); - var dbSet = db.Set(); - var query = dbSet + var queryWitsInt = db.WitsItemInt + .Where(d => d.IdTelemetry == telemetry.Id + && d.DateTime >= dateBeginUtc); + var queryWitsStr = db.WitsItemString + .Where(d => d.IdTelemetry == telemetry.Id + && d.DateTime >= dateBeginUtc); + var queryWitsFloat = db.WitsItemFloat .Where(d => d.IdTelemetry == telemetry.Id && d.DateTime >= dateBeginUtc); - if (filterByDateEnd) - query = query.Where(d => d.DateTime <= dateEnd); + var recordAllInt = GetEntityIntAsync(queryWitsInt, dateEnd, filterByDateEnd, approxPointsCount, token).Result; + var recordAllFloat = GetEntityFloatAsync(queryWitsFloat, dateEnd, filterByDateEnd, approxPointsCount, token).Result; + var recordAllStr = GetEntityStrAsync(queryWitsStr, dateEnd, filterByDateEnd, approxPointsCount, token).Result; - var fullDataCount = await query.CountAsync(token) - .ConfigureAwait(false); - - //if (fullDataCount == 0) - // return Enumerable.Empty(); - - //if (fullDataCount > 1.75 * approxPointsCount) - //{ - // var m = (int)Math.Round(1d * fullDataCount / approxPointsCount); - // if (m > 1) - // query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); - //} - - var entities = await query - .OrderBy(d => d.DateTime) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var groupRecord = entities - .GroupBy(g => g.IdRecord) - .ToList(); + var dtos = new List(); - foreach(var group in groupRecord) + if (recordAllInt.Any()) { - var dto = GetDto(group, telemetry.Id, timezone.Hours); - dtos.Add(dto); + foreach (var record in recordAllInt) + { + var existingDto = dtos.Where(r => r.Id == record.IdRecord) + .Where(r => r.Date.ToUtcDateTimeOffset(timezone.Hours) == record.DateTime) + .FirstOrDefault(); + if (existingDto is null) + { + var dto = new WitsRecordDto + { + + IdTelemetry = record.IdTelemetry, + Id = record.IdRecord, + Date = record.DateTime.ToRemoteDateTime(timezone.Hours), + }; + dto.Items.Add(record.IdItem, new JsonValue(record.Value!)); + dtos.Add(dto); + } + else + { + existingDto.Items.Add(record.IdItem, new JsonValue(record.Value!)); + } + } + } + if (recordAllStr.Any()) + { + foreach (var record in recordAllStr) + { + var existingDto = dtos.Where(r => r.Id == record.IdRecord) + .Where(r => r.Date.ToUtcDateTimeOffset(timezone.Hours) == record.DateTime) + .FirstOrDefault(); + if (existingDto is null) + { + var dto = new WitsRecordDto + { + + IdTelemetry = record.IdTelemetry, + Id = record.IdRecord, + Date = record.DateTime.ToRemoteDateTime(timezone.Hours), + }; + dto.Items.Add(record.IdItem, new JsonValue(record.Value!)); + dtos.Add(dto); + } + else + { + existingDto.Items.Add(record.IdItem, new JsonValue(record.Value!)); + } + } + } + if (recordAllFloat.Any()) + { + foreach (var record in recordAllStr) + { + var existingDto = dtos + .Where(r => r.Id == record.IdRecord) + .Where(r => r.Date.ToUtcDateTimeOffset(timezone.Hours) == record.DateTime) + .FirstOrDefault(); + if (existingDto is null) + { + var dto = new WitsRecordDto + { + + IdTelemetry = record.IdTelemetry, + Id = record.IdRecord, + Date = record.DateTime.ToRemoteDateTime(timezone.Hours), + }; + dto.Items.Add(record.IdItem, new JsonValue(record.Value!)); + dtos.Add(dto); + } + else + { + existingDto.Items.Add(record.IdItem, new JsonValue(record.Value!)); + } + } } return dtos; } @@ -104,79 +160,145 @@ namespace AsbCloudInfrastructure.Repository public async Task SaveDataAsync(int idTelemetry, WitsRecordDto dto, CancellationToken token) { - if (dto is null) - return; - var timezoneHours = telemetryService.GetTimezone(idTelemetry).Hours; - var entities = GetEntities(dto,idTelemetry,timezoneHours); - var dateMin = entities.Min(e => e.DateTime); - var dateMax = entities.Max(e => e.DateTime); - var existingEntities = await dbset - .Where(e => e.IdTelemetry == idTelemetry) - .Where(e => e.DateTime >= dateMin && e.DateTime <= dateMax) - .Select(e => e.DateTime) - .OrderBy(d => d) - .ToArrayAsync(token); - foreach (var entity in entities) - { - if (!existingEntities.Any(e => e == entity.DateTime)) - { - dbset.Add((TEntity)entity); - } - else - { - var dt = entity.DateTime; - entity.DateTime = new DateTimeOffset( - dt.Year, - dt.Month, - dt.Day, - dt.Hour, - dt.Minute, - dt.Second, - (dt.Millisecond + random.Next(1, 283)) % 1000, - dt.Offset); - dbset.Add((TEntity)entity); - } - } - await db.SaveChangesAsync(token); + //if (dto is null) + // return; + //var timezoneHours = telemetryService.GetTimezone(idTelemetry).Hours; + //var entities = GetEntities(dto, idTelemetry, timezoneHours); + //var dateMin = entities.Min(e => e.DateTime); + //var dateMax = entities.Max(e => e.DateTime); + //var existingEntities = await dbset + // .Where(e => e.IdTelemetry == idTelemetry) + // .Where(e => e.DateTime >= dateMin && e.DateTime <= dateMax) + // .Select(e => e.DateTime) + // .OrderBy(d => d) + // .ToArrayAsync(token); + //foreach (var entity in entities) + //{ + // if (!existingEntities.Any(e => e == entity.DateTime)) + // { + // dbset.Add((TEntity)entity); + // } + // else + // { + // var dt = entity.DateTime; + // entity.DateTime = new DateTimeOffset( + // dt.Year, + // dt.Month, + // dt.Day, + // dt.Hour, + // dt.Minute, + // dt.Second, + // (dt.Millisecond + random.Next(1, 283)) % 1000, + // dt.Offset); + // dbset.Add((TEntity)entity); + // } + //} + //await db.SaveChangesAsync(token); } - private static IEnumerable> GetEntities(WitsRecordDto recordItems, int idTelemetry, double timezoneHours) - { - var itemsCount = recordItems.Items.Count; - var entities = new List>(itemsCount); - - foreach (var dtoItems in recordItems.Items) + private static async Task> GetEntityIntAsync(IQueryable query, + DateTimeOffset dateEnd, bool filterByDateEnd, int approxPointsCount + , CancellationToken token) + { + if (filterByDateEnd) + query = query.Where(d => d.DateTime <= dateEnd); + + var fullDataCount = await query.CountAsync(token) + .ConfigureAwait(false); + + if (fullDataCount == 0) + return Enumerable.Empty(); + + if (fullDataCount > 1.75 * approxPointsCount) { - var entityItems = new WitsItemBase - { - IdTelemetry = idTelemetry, - DateTime = recordItems.Date.ToUtcDateTimeOffset(timezoneHours), - IdRecord = recordItems.Id, - IdItem = dtoItems.Key, - Value = System.Text.Json.JsonSerializer.Deserialize(dtoItems.Value.ToString()) - }; - entities.Add(entityItems); - } + var m = (int)Math.Round(1d * fullDataCount / approxPointsCount); + if (m > 1) + query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); + } + + var entities = await query + .OrderBy(d => d.DateTime) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); return entities; } - private static WitsRecordDto GetDto(IEnumerable> entities, int idTelemetry, double timezoneHours) + private static async Task> GetEntityFloatAsync(IQueryable query, + DateTimeOffset dateEnd, bool filterByDateEnd, int approxPointsCount + , CancellationToken token) { - var entity = entities.First(); - var dto = new WitsRecordDto - { - Id = entity.IdRecord, - Date = entity.DateTime.ToRemoteDateTime(timezoneHours), - IdTelemetry = idTelemetry - }; + if (filterByDateEnd) + query = query.Where(d => d.DateTime <= dateEnd); - foreach (var entityItems in entities) + var fullDataCount = await query.CountAsync(token) + .ConfigureAwait(false); + + if (fullDataCount == 0) + return Enumerable.Empty(); + + if (fullDataCount > 1.75 * approxPointsCount) { - var valueItem = new JsonValue(entityItems.Value!); - dto.Items.Add(entityItems.IdItem, valueItem); + var m = (int)Math.Round(1d * fullDataCount / approxPointsCount); + if (m > 1) + query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); } - return dto; + + var entities = await query + .OrderBy(d => d.DateTime) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + return entities; } + + private static async Task> GetEntityStrAsync(IQueryable query, + DateTimeOffset dateEnd, bool filterByDateEnd, int approxPointsCount + , CancellationToken token) + { + if (filterByDateEnd) + query = query.Where(d => d.DateTime <= dateEnd); + + var fullDataCount = await query.CountAsync(token) + .ConfigureAwait(false); + + if (fullDataCount == 0) + return Enumerable.Empty(); + + if (fullDataCount > 1.75 * approxPointsCount) + { + var m = (int)Math.Round(1d * fullDataCount / approxPointsCount); + if (m > 1) + query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); + } + + var entities = await query + .OrderBy(d => d.DateTime) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + return entities; + } + + //private static void GetEntities(WitsRecordDto recordItems, int idTelemetry, double timezoneHours) + //{ + // var itemsCount = recordItems.Items.Count; + // var entities = new List>(itemsCount); + + // foreach (var dtoItems in recordItems.Items) + // { + // var entityItems = new WitsItemBase + // { + // IdTelemetry = idTelemetry, + // DateTime = recordItems.Date.ToUtcDateTimeOffset(timezoneHours), + // IdRecord = recordItems.Id, + // IdItem = dtoItems.Key, + // Value = System.Text.Json.JsonSerializer.Deserialize(dtoItems.Value.ToString()) + // }; + // entities.Add(entityItems); + // } + // return entities; + //} } #nullable disable } diff --git a/AsbCloudWebApi/Controllers/GTR/GtrWitsController.cs b/AsbCloudWebApi/Controllers/GTR/GtrWitsController.cs index 0c5b3c37..023543b3 100644 --- a/AsbCloudWebApi/Controllers/GTR/GtrWitsController.cs +++ b/AsbCloudWebApi/Controllers/GTR/GtrWitsController.cs @@ -20,19 +20,19 @@ namespace AsbCloudWebApi.Controllers.GTR { protected readonly IWellService wellService; private readonly ITelemetryService telemetryService; - //private readonly IGtrRepository gtrRepository; + private readonly IGtrRepository gtrRepository; private readonly IHubContext telemetryHubContext; //public string SirnalRMethodGetDataName { get; protected set; } = "ReceiveData"; public GtrWitsController( ITelemetryService telemetryService, - // IGtrRepository gtrRepository, + IGtrRepository gtrRepository, IWellService wellService, IHubContext telemetryHubContext) { this.telemetryService = telemetryService; - //this.gtrRepository = gtrRepository; + this.gtrRepository = gtrRepository; this.wellService = wellService; this.telemetryHubContext = telemetryHubContext; } @@ -41,32 +41,32 @@ namespace AsbCloudWebApi.Controllers.GTR /// Возвращает данные САУБ по скважине. /// По умолчанию за последние 10 минут. /// - /// id скважины - /// дата начала выборки. По умолчанию: текущее время - intervalSec - /// интервал времени даты начала выборки, секунды - /// желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. - /// Токен завершения задачи + /// id скважины + /// дата начала выборки.По умолчанию: текущее время - intervalSec + /// интервал времени даты начала выборки, секунды + /// желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. + /// Токен завершения задачи /// - //[HttpGet("{idWell}")] - ////[Permission] - //public async Task>> GetDataAsync(int idWell, DateTime begin = default, - // int intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default) - //{ - // //int? idCompany = User.GetCompanyId(); + [HttpGet("{idWell}")] + //[Permission] + public async Task>> GetDataAsync(int idWell, DateTime begin = default, + int intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default) + { + //int? idCompany = User.GetCompanyId(); - // //if (idCompany is null) - // // return Forbid(); + //if (idCompany is null) + // return Forbid(); - // //bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - // // idWell, token).ConfigureAwait(false); + //bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + // idWell, token).ConfigureAwait(false); - // //if (!isCompanyOwnsWell) - // // return Forbid(); + //if (!isCompanyOwnsWell) + // return Forbid(); - // //var content = await gtrRepository.GetAsync(idWell, begin, - // // intervalSec, approxPointsCount, token).ConfigureAwait(false); + var content = await gtrRepository.GetAsync(idWell, begin, + intervalSec, approxPointsCount, token).ConfigureAwait(false); - // //return Ok(content); - //} + return Ok(content); + } } }