using AsbCloudApp.Services; 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 { #nullable enable /// /// CRUD сервис для работы с БД /// /// /// public class CrudServiceBase : ICrudService where TDto : AsbCloudApp.Data.IId where TEntity : class, IId { protected readonly IAsbCloudDbContext dbContext; protected readonly DbSet dbSet; protected readonly Func> GetQuery; public CrudServiceBase(IAsbCloudDbContext context) { dbContext = context; dbSet = context.Set(); GetQuery = () => dbSet; } public CrudServiceBase(IAsbCloudDbContext dbContext, ISet includes) { this.dbContext = dbContext; dbSet = dbContext.Set(); GetQuery = () => { IQueryable query = dbSet; foreach (var include in includes) query = query.Include(include); return query; }; } public CrudServiceBase(IAsbCloudDbContext context, Func, IQueryable> makeQuery) { dbContext = context; dbSet = context.Set(); GetQuery = () => makeQuery(dbSet); } /// public virtual async Task> GetAllAsync(CancellationToken token = default) { var entities = await GetQuery() //.OrderBy(e => e.Id) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var dtos = entities.Select(Convert).ToList(); return dtos; } /// public virtual async Task GetOrDefaultAsync(int id, CancellationToken token = default) { var entity = await GetQuery() .AsNoTracking() .FirstOrDefaultAsync(e => e.Id == id, token) .ConfigureAwait(false); if (entity == default) return default; var dto = Convert(entity); return dto; } /// public virtual TDto? GetOrDefault(int id) { var entity = GetQuery() .AsNoTracking() .FirstOrDefault(e => e.Id == id); if (entity == default) return default; var dto = Convert(entity); return dto; } /// public virtual async Task InsertAsync(TDto item, CancellationToken token = default) { var entity = Convert(item); entity.Id = 0; var entry = dbSet.Add(entity); await dbContext.SaveChangesAsync(token); entry.State = EntityState.Detached; return entity.Id; } /// public virtual async Task InsertRangeAsync(IEnumerable items, CancellationToken token = default) { if (!items.Any()) return 0; var entities = items.Select(i => { var entity = Convert(i); entity.Id = 0; return entity; }); var entries = new List(items.Count()); foreach (var entity in entities) { var entry = dbSet.Add(entity); entries.Add(entry); } var affected = await dbContext.SaveChangesAsync(token); entries.ForEach(e => e.State = EntityState.Detached); return affected; } /// public virtual async Task UpdateAsync(TDto item, CancellationToken token = default) { var existingEntity = await dbSet .AsNoTracking() .FirstOrDefaultAsync(e => e.Id == item.Id, token) .ConfigureAwait(false); if (existingEntity is null) return ICrudService.ErrorIdNotFound; var entity = Convert(item); var entry = dbSet.Update(entity); await dbContext.SaveChangesAsync(token); entry.State = EntityState.Detached; return entry.Entity.Id; } public virtual async Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token) { var ids = dtos.Select(d => d.Id); var existingEntities = await dbSet .AsNoTracking() .Where(d => ids.Contains(d.Id)) .Select(d => d.Id) .ToListAsync(token) .ConfigureAwait(false); if (ids.Count() > existingEntities.Count) return ICrudService.ErrorIdNotFound; foreach (var dto in dtos) { var entity = Convert(dto); var entry = dbSet.Update(entity); } var affected = await dbContext.SaveChangesAsync(token); return affected; } /// public virtual Task DeleteAsync(int id, CancellationToken token = default) { var entity = dbSet .AsNoTracking() .FirstOrDefault(e => e.Id == id); if (entity == default) return Task.FromResult(ICrudService.ErrorIdNotFound); var entry = dbSet.Remove(entity); var affected = dbContext.SaveChangesAsync(token); entry.State = EntityState.Detached; return affected; } protected virtual TDto Convert(TEntity src) => src.Adapt(); protected virtual TEntity Convert(TDto src) => src.Adapt(); } #nullable disable }