using AsbCloudApp; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Mapster; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class CrudCacheServiceBase<TDto, TModel> : ICrudService<TDto> where TDto : AsbCloudApp.Data.IId where TModel : class, AsbCloudDb.Model.IId { private CacheTable<TModel> cache = null; private readonly IAsbCloudDbContext db; private readonly CacheDb cacheDb; public ISet<string> Includes { get; } = new SortedSet<string>(); protected CacheTable<TModel> Cache { get { if(cache is null) cache = cacheDb.GetCachedTable<TModel>((AsbCloudDbContext)db, Includes); return cache; } } public CrudCacheServiceBase(IAsbCloudDbContext db, CacheDb cacheDb) { this.db = db; this.cacheDb = cacheDb; } public virtual async Task<int> InsertAsync(TDto newItem, CancellationToken token = default) { var entity = Convert(newItem); var insertedEntity = await Cache.InsertAsync(entity, token) .ConfigureAwait(false); return insertedEntity?.Id??-1; } public virtual async Task<int> InsertRangeAsync(IEnumerable<TDto> dtos, CancellationToken token) { var entities = dtos.Select(Convert); var insertedEntities = await Cache.InsertAsync(entities, token) .ConfigureAwait(false); return insertedEntities?.Count()??0; } public virtual async Task<IEnumerable<TDto>> GetAllAsync(CancellationToken token) { var entities = await Cache.WhereAsync(token) .ConfigureAwait(false); var dtos = entities?.Select(Convert); return dtos; } public virtual async Task<TDto> GetAsync(int id, CancellationToken token) { var entity = await Cache .FirstOrDefaultAsync(p => p.Id == id, token) .ConfigureAwait(false); if (entity is null) return default; var dto = Convert(entity); return dto; } public virtual async Task<int> UpdateAsync(int id, TDto dto, CancellationToken token) { if (dto.Id != id) { var exist = await Cache.ContainsAsync(i=>i.Id == dto.Id, token) .ConfigureAwait(false); if (exist) return -1; await Cache.RemoveAsync(i => i.Id == id, token) .ConfigureAwait(false); } var entity = Convert(dto); await Cache.UpsertAsync(entity, token) .ConfigureAwait(false); return 1; } public virtual async Task<int> DeleteAsync(int id, CancellationToken token) { var affected = await Cache.RemoveAsync(p => p.Id == id, token) .ConfigureAwait(false); return affected; } public virtual async Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default) { var affected = await Cache.RemoveAsync(p => ids.Contains(p.Id), token) .ConfigureAwait(false); return affected; } protected virtual TModel Convert(TDto src) { var entity = src.Adapt<TModel>(); return entity; } protected virtual TDto Convert(TModel src) { var dto = src.Adapt<TDto>(); return dto; } } }