using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Mapster; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class MeasureService : IMeasureService { private readonly IAsbCloudDbContext db; private readonly CacheTable cacheCategories; public MeasureService(IAsbCloudDbContext db, Cache.CacheDb cacheDb) { this.db = db; cacheCategories = cacheDb.GetCachedTable((DbContext)db); } public async Task> GetCategoriesAsync(CancellationToken token) { var entities = await cacheCategories.WhereAsync(token).ConfigureAwait(false); var dto = entities.ToDictionary(e=>e.Id, e=>e.Name); return dto; } public async Task> GetAllLastAsync(int idWell, CancellationToken token) { var categories = await cacheCategories.WhereAsync(token).ConfigureAwait(false); if (!categories.Any()) return default; var queries = categories.Select(c => db.Measures .Where(m => m.IdWell == idWell && m.IdCategory == c.Id && !m.IsDeleted) .OrderByDescending(m => m.Timestamp) .Take(1) ); var qi = queries.GetEnumerator(); qi.MoveNext(); var query = qi.Current; while (qi.MoveNext()) query = query.Union(qi.Current); //var query = db.Measures // .Where(e => e.IdWell == idWell) // .GroupBy(e => e.IdCategory) // .Select(g => g.Where(e => e.Timestamp == g.Max(m => m.Timestamp)).First()); //var query = db.Measures // .Where(m => m.IdWell == idWell && m.Timestamp == db.Measures // .Where(subm => subm.IdWell == m.IdWell && subm.IdCategory == m.IdCategory).Max(subm => subm.Timestamp)); var entities = await query .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var dtos = entities.Adapt((d, s) => d.CategoryName = s.Category.Name); return dtos; } public async Task> GetHisoryAsync(int idWell, int idCategory, CancellationToken token) { var query = db.Measures.Include(m => m.Category) .Where(m => m.IdWell == idWell && m.IdCategory == idCategory && !m.IsDeleted); var entities = await query .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var dtos = entities.Adapt((d, s) => d.CategoryName = s.Category.Name); return dtos; } public Task InsertAsync(int idWell, MeasureDto data, CancellationToken token) { if (data.IdCategory < 1) throw new ArgumentException("wrong idCategory", nameof(data)); if (data.Data is null) throw new ArgumentException("data.data is not optional", nameof(data)); var entity = data.Adapt(); entity.Id = 0; entity.IdWell = idWell; db.Measures.Add(entity); return db.SaveChangesAsync(token); } public async Task UpdateAsync(int idWell, MeasureDto data, CancellationToken token) { if (data.Id < 1) throw new ArgumentException("wrong id", nameof(data)); if (data.IdCategory < 1) throw new ArgumentException("wrong idCategory", nameof(data)); if (data.Data is null) throw new ArgumentException("data.data is not optional", nameof(data)); var entity = await db.Measures .Where(m => m.Id == data.Id && !m.IsDeleted) .FirstOrDefaultAsync(token) .ConfigureAwait(false); if (entity is null) throw new ArgumentException("id doesn't exist", nameof(data)); entity.Timestamp = data.Timestamp; entity.Data = data.Data; return await db.SaveChangesAsync(token).ConfigureAwait(false); } public async Task MarkAsDeleteAsync(int idWell, int idData, CancellationToken token) { if (idData < 1) throw new ArgumentException("wrong id", nameof(idData)); var entity = await db.Measures.Where(m => m.IdWell == idWell && m.Id == idData) .FirstOrDefaultAsync(token) .ConfigureAwait(false); entity.IsDeleted = true; return await db.SaveChangesAsync(token).ConfigureAwait(false); } public Task DeleteAsync(int idWell, int idData, CancellationToken token) { if (idData < 1) throw new ArgumentException("wrong id", nameof(idData)); db.Measures.RemoveRange(db.Measures.Where(m => m.IdWell == idWell && m.Id == idData)); return db.SaveChangesAsync(token); } } }