DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/CrudServiceBase.cs
2022-06-15 14:57:37 +05:00

186 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// CRUD сервис для работы с БД
/// </summary>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TEntity"></typeparam>
public class CrudServiceBase<TDto, TEntity> : ICrudService<TDto>
where TDto : AsbCloudApp.Data.IId
where TEntity : class, AsbCloudDb.Model.IId
{
protected readonly IAsbCloudDbContext dbContext;
protected readonly DbSet<TEntity> dbSet;
protected readonly Func<IQueryable<TEntity>> GetQuery;
public CrudServiceBase(IAsbCloudDbContext context)
{
this.dbContext = context;
dbSet = context.Set<TEntity>();
GetQuery = () => dbSet;
}
public CrudServiceBase(IAsbCloudDbContext dbContext, ISet<string> includes)
{
this.dbContext = dbContext;
dbSet = dbContext.Set<TEntity>();
GetQuery = () =>
{
IQueryable<TEntity> query = dbSet;
foreach (var include in includes)
query = query.Include(include);
return query;
};
}
public CrudServiceBase(IAsbCloudDbContext context, Func<DbSet<TEntity>, IQueryable<TEntity>> makeQuery)
{
this.dbContext = context;
dbSet = context.Set<TEntity>();
GetQuery = () => makeQuery(dbSet);
}
/// <inheritdoc/>
public virtual async Task<IEnumerable<TDto>> 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;
}
/// <inheritdoc/>
public virtual async Task<TDto?> GetAsync(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;
}
/// <inheritdoc/>
public virtual TDto? Get(int id)
{
var entity = GetQuery()
.AsNoTracking()
.FirstOrDefault(e => e.Id == id);
if (entity == default)
return default;
var dto = Convert(entity);
return dto;
}
/// <inheritdoc/>
public virtual async Task<int> 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;
}
/// <inheritdoc/>
public virtual async Task<int> InsertRangeAsync(IEnumerable<TDto> 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<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry>(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;
}
/// <inheritdoc/>
public virtual async Task<int> 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<TDto>.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<int> UpdateRangeAsync(IEnumerable<TDto> 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<TDto>.ErrorIdNotFound;
foreach (var dto in dtos)
{
var entity = Convert(dto);
var entry = dbSet.Update(entity);
}
var affected = await dbContext.SaveChangesAsync(token);
return affected;
}
/// <inheritdoc/>
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(ICrudService<TDto>.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<TDto>();
protected virtual TEntity Convert(TDto src) => src.Adapt<TEntity>();
}
#nullable disable
}