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
}