using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; using Mapster; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Repository; public class DetectedOperationRepository : IDetectedOperationRepository { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; public DetectedOperationRepository( IAsbCloudDbContext db, ITelemetryService telemetryService) { this.db = db; this.telemetryService = telemetryService; } public async Task Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token) { var query = BuildQuery(request); db.Set().RemoveRange(query); return await db.SaveChangesAsync(token); } public async Task DeleteRange(int idUser, IEnumerable ids, CancellationToken token) { var query = db.Set() .Where(e => ids.Contains( e.Id)); db.Set() .RemoveRange(query); return await db.SaveChangesAsync(token); } public async Task> Get(DetectedOperationByTelemetryRequest request, CancellationToken token) { var query = BuildQuery(request) .Include(o => o.OperationCategory); var entities = await query.ToArrayAsync(token); var offset = telemetryService.GetTimezone(request.IdTelemetry).Offset; var dtos = entities.Select(o => Convert(o, offset)); return dtos; } public async Task Insert(int? idUser, IEnumerable dtos, CancellationToken token) { if(!dtos.Any()) return 0; var entities = dtos.Select(Convert); var dbset = db.Set(); foreach(var entity in entities) { entity.Id = default; dbset.Add(entity); } return await db.SaveChangesWithExceptionHandling(token); } public async Task Update(int idUser, IEnumerable dtos, CancellationToken token) { if (!dtos.Any()) return 0; var ids = dtos .Select(o => o.Id) .Distinct() .ToArray(); if (ids.Any(id => id == default)) throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id"); if (ids.Length != dtos.Count()) throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id"); var dbSet = db.Set(); var existingEntitiesCount = await dbSet .Where(o => ids.Contains(o.Id)) .CountAsync(token); if (ids.Length != existingEntitiesCount) throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД"); var entities = dtos .Select(Convert) .ToArray(); var entries = new Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry[entities.Length]; for(var i = 0; i < entities.Length; i++) entries[i] = dbSet.Update(entities[i]); var result = await db.SaveChangesWithExceptionHandling(token); for (var i = 0; i < entries.Length; i++) entries[i].State = EntityState.Detached; return result; } public async Task UpdateOrInsert(int idUser, IEnumerable dtos, CancellationToken token) { var result = 0; var itemsToInsert = dtos.Where(e => e.Id == 0); if (itemsToInsert.Any()) result += await Insert(idUser, itemsToInsert, token); var itemsToUpdate = dtos.Where(e => e.Id != 0); if (itemsToUpdate.Any()) result += await Update(idUser, itemsToUpdate, token); return result; } private IQueryable BuildQuery(DetectedOperationByTelemetryRequest request) { var query = db.Set() .Where(o => o.IdTelemetry == request.IdTelemetry); if (request.IdsCategories.Any()) query = query.Where(o => request.IdsCategories.Contains(o.IdCategory)); if (request.GeDepthStart is not null) query = query.Where(o => o.DepthStart >= request.GeDepthStart); if (request.LeDepthEnd is not null) query = query.Where(o => o.DepthEnd <= request.LeDepthEnd); if (request.GeDateStart is not null) { var geDate = request.GeDateStart.Value.ToUniversalTime(); query = query.Where(o => o.DateStart >= geDate); } if (request.LeDateEnd is not null) { var leDate = request.LeDateEnd.Value.ToUniversalTime(); query = query.Where(o => o.DateEnd <= leDate); } if (request.SortFields?.Any() == true) { query = query.SortBy(request.SortFields); } else query = query .OrderBy(o => o.DateStart) .ThenBy(o => o.DepthStart); if (request.Skip.HasValue) query = query.Skip((int)request.Skip); if (request.Take.HasValue) query = query.Take((int)request.Take); return query; } private static DetectedOperationDto Convert(DetectedOperation entity, TimeSpan offset) { var dto = entity.Adapt(); dto.DateStart = entity.DateStart.ToOffset(offset); dto.DateEnd = entity.DateEnd.ToOffset(offset); return dto; } private static DetectedOperation Convert(DetectedOperationDto dto) { var entity = dto.Adapt(); entity.DateStart = dto.DateStart.ToUniversalTime(); entity.DateEnd = dto.DateEnd.ToUniversalTime(); return entity; } }