using AsbCloudApp.Data; 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.Services { public class CrudServiceBase<TDto, TModel> : ICrudService<TDto>, IConverter<TDto, TModel> where TDto : AsbCloudApp.Data.IId where TModel : class, AsbCloudDb.Model.IId { protected readonly IAsbCloudDbContext context; protected readonly DbSet<TModel> dbSet; public List<string> Incledes { get; } = new List<string>(); public CrudServiceBase(IAsbCloudDbContext context) { this.context = context; dbSet = context.Set<TModel>(); } public virtual async Task<PaginationContainer<TDto>> GetPageAsync(int skip = 0, int take = 32, CancellationToken token = default) { var query = GetQueryWithIncludes(); var count = await query .CountAsync(token) .ConfigureAwait(false); var container = new PaginationContainer<TDto> { Skip = skip, Take = take, Count = count, }; if (skip >= count) return container; query = query .OrderBy(e => e.Id); if (skip > 0) query = query.Skip(skip); query = query.Take(take); var entities = await query .ToListAsync(token) .ConfigureAwait(false); container.Items = entities .Select(entity => Convert(entity)) .ToList(); return container; } public virtual async Task<IEnumerable<TDto>> GetAllAsync(CancellationToken token = default) { var query = GetQueryWithIncludes(); var entities = await query .OrderBy(e => e.Id) .ToListAsync(token).ConfigureAwait(false); var dto = entities.Select(entity => Convert(entity)); return dto; } public virtual async Task<TDto> GetAsync(int id, CancellationToken token = default) { var query = GetQueryWithIncludes(); var entity = await query .FirstOrDefaultAsync(e => e.Id == id, token).ConfigureAwait(false); var dto = Convert(entity); return dto; } public virtual async Task<int> InsertAsync(TDto item, CancellationToken token = default) { var entity = Convert(item); entity.Id = 0; dbSet.Add(entity); await context.SaveChangesAsync(token); return entity.Id; } public virtual Task<int> InsertRangeAsync(IEnumerable<TDto> items, CancellationToken token = default) { var entities = items.Select(i => { var entity = Convert(i); entity.Id = 0; return entity; }); dbSet.AddRange(entities); return context.SaveChangesAsync(token); } public virtual Task<int> UpdateAsync(int id, TDto item, CancellationToken token = default) { var entity = Convert(item); dbSet.Update(entity); return context.SaveChangesAsync(token); } public virtual Task<int> DeleteAsync(int id, CancellationToken token = default) { var entity = dbSet.AsNoTracking() .FirstOrDefault(e => e.Id == id); if (entity == default) return Task.FromResult(0); dbSet.Remove(entity); return context.SaveChangesAsync(token); } public virtual Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default) { var entities = dbSet.Where(e => ids.Contains(e.Id)).AsNoTracking(); if (entities == default) return Task.FromResult(0); dbSet.RemoveRange(entities); return context.SaveChangesAsync(token); } public virtual TDto Convert(TModel src) => src.Adapt<TDto>(); public virtual TModel Convert(TDto src) => src.Adapt<TModel>(); private IQueryable<TModel> GetQueryWithIncludes() { IQueryable<TModel> query = dbSet; foreach (var include in Incledes) query = query.Include(include); return query; } } }