using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using System; using System.Collections.Generic; using System.Linq; using Mapster; using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; using System.Threading; using AsbCloudInfrastructure.Services.Cache; namespace AsbCloudInfrastructure.Services { public class WellSectionService: IWellSectionService { private readonly IAsbCloudDbContext context; private readonly DbSet dbSet; private readonly CacheTable cachedSectionsTypes; public WellSectionService(IAsbCloudDbContext context, Cache.CacheDb cache) { this.context = context; dbSet = context.Set(); cachedSectionsTypes = cache.GetCachedTable((DbContext)context); } public Task GetTypesAsync(CancellationToken token) => context.WellSectionTypes.Select(e => e.Caption).Distinct().AsNoTracking().ToArrayAsync(token); public async Task> GetAllByWellIdAsync(int idWell, int skip, int take, CancellationToken token = default) { var query = dbSet .Include(s => s.WellSectionType) .Where(s => s.IdWell == idWell) .AsNoTracking(); var result = new PaginationContainer { Skip = skip, Take = take, Count = await query.CountAsync(token).ConfigureAwait(false), }; query = query .OrderBy(e => e.WellDepthPlan); if (skip > 0) query = query.Skip(skip); query = query.Take(take); var entities = await query.Take(take).ToListAsync(token).ConfigureAwait(false); foreach (var item in entities) { var dto = item.Adapt(); dto.SectionType = item.WellSectionType.Caption; result.Items.Add(dto); } return result; } public async Task GetAsync(int id, CancellationToken token = default) { var entity = await dbSet .Include(s => s.WellSectionType) .FirstOrDefaultAsync(e => e.Id == id, token) .ConfigureAwait(false); if (entity is null) return null; var dto = entity.Adapt(); dto.SectionType = entity.WellSectionType.Caption; return dto; } public async Task InsertAsync(WellSectionDto item, int idWell, CancellationToken token = default) { var sectionType = await GetWellSectionTypeFromCacheAndAssertAsync(item.SectionType); var entity = item.Adapt(); entity.Id = default; entity.IdWell = idWell; entity.IdWellSectionType = sectionType.Id; var dbEntity = dbSet.Add(entity); await context.SaveChangesAsync(token).ConfigureAwait(false); var dto = dbEntity.Entity.Adapt(); dto.SectionType = sectionType.Caption; return dto; } public async Task> InsertRangeAsync(int idWell, IEnumerable items, CancellationToken token = default) { var dbEntities = new Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry[items.Count()]; for (int i = 0; i < dbEntities.Length; i++) { var sectionType = await GetWellSectionTypeFromCacheAndAssertAsync(items.ElementAt(i).SectionType, token); var item = items.ElementAt(i).Adapt(); item.IdWell = idWell; item.IdWellSectionType = sectionType.Id; dbEntities[i] = dbSet.Add(item); } await context.SaveChangesAsync(token).ConfigureAwait(false); var dtos = dbEntities.Select((e) => { var dto = e.Entity.Adapt(); var sectionType = cachedSectionsTypes.FirstOrDefault(s => s.Id == e.Entity.IdWellSectionType); dto.SectionType = sectionType.Caption; return dto; }); return dtos; } public async Task UpdateAsync(int idWell, int idSection, WellSectionDto item, CancellationToken token = default) { var sectionType = await GetWellSectionTypeFromCacheAndAssertAsync(item.SectionType, token) .ConfigureAwait(false); var entity = item.Adapt(); entity.Id = idSection; entity.IdWell = idWell; entity.IdWellSectionType = sectionType.Id; var dbEntity = dbSet.Update(entity); await context.SaveChangesAsync(token).ConfigureAwait(false); var dto = dbEntity.Entity.Adapt(); dto.SectionType = sectionType.Caption; return dto; } public Task DeleteAsync(IEnumerable ids, CancellationToken token = default) { var entities = dbSet.Where(e => ids.Contains(e.Id)); dbSet.RemoveRange(entities); return context.SaveChangesAsync(token); } private async Task GetWellSectionTypeFromCacheAndAssertAsync(string wellSectionType, CancellationToken token = default) { if (string.IsNullOrEmpty(wellSectionType)) throw new ArgumentException("Тип секции должен быть указан", nameof(WellSectionDto.SectionType)); var sectionType = await cachedSectionsTypes .FirstOrDefaultAsync(s => s.Caption.Equals(wellSectionType, StringComparison.OrdinalIgnoreCase), token) .ConfigureAwait(false); if (sectionType is null) { throw new ArgumentException($"Тип секции '{wellSectionType}' отсутствует в справочнике", nameof(WellSectionDto.SectionType)) ; //sectionType = await cachedSectionsTypes.InsertAsync(new WellSectionType { Caption = item.SectionType}, token); } return sectionType; } } }