2022-06-06 15:43:47 +05:00
|
|
|
|
using AsbCloudApp.Services;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
using AsbCloudDb.Model;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2021-09-10 11:28:57 +05:00
|
|
|
|
using System;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2024-04-08 09:17:17 +05:00
|
|
|
|
using AsbCloudApp.Exceptions;
|
2024-03-26 13:35:36 +05:00
|
|
|
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
|
2022-06-16 12:33:05 +05:00
|
|
|
|
namespace AsbCloudInfrastructure.Repository
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// CRUD сервис для работы с БД
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TDto"></typeparam>
|
|
|
|
|
/// <typeparam name="TEntity"></typeparam>
|
2022-12-01 15:56:11 +05:00
|
|
|
|
public class CrudRepositoryBase<TDto, TEntity> : QueryContainer<TEntity>, ICrudRepository<TDto>
|
2021-09-17 16:24:01 +05:00
|
|
|
|
where TDto : AsbCloudApp.Data.IId
|
2022-06-16 12:33:05 +05:00
|
|
|
|
where TEntity : class, IId
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2022-12-01 15:56:11 +05:00
|
|
|
|
public CrudRepositoryBase(IAsbCloudDbContext context)
|
|
|
|
|
: base(context)
|
|
|
|
|
{ }
|
2021-09-10 11:28:57 +05:00
|
|
|
|
|
2022-12-01 15:56:11 +05:00
|
|
|
|
public CrudRepositoryBase(IAsbCloudDbContext context, Func<DbSet<TEntity>, IQueryable<TEntity>> makeQuery)
|
|
|
|
|
: base(context, makeQuery)
|
|
|
|
|
{ }
|
2021-09-29 09:57:11 +05:00
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-12-07 15:23:10 +05:00
|
|
|
|
public virtual async Task<IEnumerable<TDto>> GetAllAsync(CancellationToken token)
|
2022-06-06 15:43:47 +05:00
|
|
|
|
{
|
|
|
|
|
var entities = await GetQuery()
|
|
|
|
|
.AsNoTracking()
|
2021-09-10 11:28:57 +05:00
|
|
|
|
.ToListAsync(token)
|
|
|
|
|
.ConfigureAwait(false);
|
2022-06-06 15:43:47 +05:00
|
|
|
|
var dtos = entities.Select(Convert).ToList();
|
|
|
|
|
return dtos;
|
2021-09-10 11:28:57 +05:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-12-07 15:23:10 +05:00
|
|
|
|
public virtual async Task<TDto?> GetOrDefaultAsync(int id, CancellationToken token)
|
2021-09-10 11:28:57 +05:00
|
|
|
|
{
|
2022-06-06 15:43:47 +05:00
|
|
|
|
var entity = await GetQuery()
|
|
|
|
|
.AsNoTracking()
|
|
|
|
|
.FirstOrDefaultAsync(e => e.Id == id, token)
|
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
if (entity == default)
|
|
|
|
|
return default;
|
|
|
|
|
var dto = Convert(entity);
|
2021-09-10 11:28:57 +05:00
|
|
|
|
return dto;
|
2022-08-01 13:55:51 +05:00
|
|
|
|
}
|
2021-09-10 11:28:57 +05:00
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-06-16 12:33:05 +05:00
|
|
|
|
public virtual TDto? GetOrDefault(int id)
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2022-06-06 15:43:47 +05:00
|
|
|
|
var entity = GetQuery()
|
|
|
|
|
.AsNoTracking()
|
|
|
|
|
.FirstOrDefault(e => e.Id == id);
|
|
|
|
|
if (entity == default)
|
|
|
|
|
return default;
|
2021-09-10 11:28:57 +05:00
|
|
|
|
var dto = Convert(entity);
|
2021-08-10 14:36:35 +05:00
|
|
|
|
return dto;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-12-07 15:23:10 +05:00
|
|
|
|
public virtual async Task<int> InsertAsync(TDto item, CancellationToken token)
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2021-09-10 11:28:57 +05:00
|
|
|
|
var entity = Convert(item);
|
2021-10-14 17:13:57 +05:00
|
|
|
|
entity.Id = 0;
|
2022-06-15 14:57:37 +05:00
|
|
|
|
var entry = dbSet.Add(entity);
|
2022-06-06 15:43:47 +05:00
|
|
|
|
await dbContext.SaveChangesAsync(token);
|
2022-06-09 17:25:26 +05:00
|
|
|
|
entry.State = EntityState.Detached;
|
2021-11-25 11:55:52 +05:00
|
|
|
|
return entity.Id;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-12-07 15:23:10 +05:00
|
|
|
|
public virtual async Task<int> InsertRangeAsync(IEnumerable<TDto> items, CancellationToken token)
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2022-06-06 15:43:47 +05:00
|
|
|
|
if (!items.Any())
|
2022-06-09 17:25:26 +05:00
|
|
|
|
return 0;
|
2022-04-11 18:00:34 +05:00
|
|
|
|
var entities = items.Select(i =>
|
|
|
|
|
{
|
2021-10-14 17:13:57 +05:00
|
|
|
|
var entity = Convert(i);
|
|
|
|
|
entity.Id = 0;
|
|
|
|
|
return entity;
|
|
|
|
|
});
|
2024-03-26 13:35:36 +05:00
|
|
|
|
var entries = new List<EntityEntry>(items.Count());
|
2022-06-09 17:25:26 +05:00
|
|
|
|
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;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-12-07 15:23:10 +05:00
|
|
|
|
public virtual async Task<int> UpdateAsync(TDto item, CancellationToken token)
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2022-06-06 15:43:47 +05:00
|
|
|
|
var existingEntity = await dbSet
|
|
|
|
|
.AsNoTracking()
|
2022-06-09 11:19:52 +05:00
|
|
|
|
.FirstOrDefaultAsync(e => e.Id == item.Id, token)
|
2022-06-06 15:43:47 +05:00
|
|
|
|
.ConfigureAwait(false);
|
2022-06-15 14:57:37 +05:00
|
|
|
|
|
2021-12-03 15:03:33 +05:00
|
|
|
|
if (existingEntity is null)
|
2022-12-01 15:56:11 +05:00
|
|
|
|
return ICrudRepository<TDto>.ErrorIdNotFound;
|
2022-06-15 14:57:37 +05:00
|
|
|
|
|
2021-09-10 11:28:57 +05:00
|
|
|
|
var entity = Convert(item);
|
2022-06-06 15:43:47 +05:00
|
|
|
|
var entry = dbSet.Update(entity);
|
|
|
|
|
await dbContext.SaveChangesAsync(token);
|
2022-06-09 17:25:26 +05:00
|
|
|
|
entry.State = EntityState.Detached;
|
2022-06-06 15:43:47 +05:00
|
|
|
|
return entry.Entity.Id;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
}
|
2024-03-20 12:52:28 +05:00
|
|
|
|
|
|
|
|
|
public virtual async Task<int> UpdateRangeAsync(IEnumerable<TDto> dtos, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
if (!dtos.Any())
|
|
|
|
|
return 0;
|
2024-04-08 09:17:17 +05:00
|
|
|
|
|
|
|
|
|
var ids = dtos
|
|
|
|
|
.Select(o => o.Id)
|
|
|
|
|
.Distinct()
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
if (ids.Any(id => id == default))
|
|
|
|
|
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id");
|
|
|
|
|
|
|
|
|
|
if (ids.Length != dtos.Count())
|
|
|
|
|
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
|
|
|
|
|
|
|
|
|
|
var dbSet = dbContext.Set<TEntity>();
|
|
|
|
|
|
|
|
|
|
var existingEntitiesCount = await dbSet
|
|
|
|
|
.Where(o => ids.Contains(o.Id))
|
2024-03-20 12:52:28 +05:00
|
|
|
|
.CountAsync(token);
|
2024-04-08 09:17:17 +05:00
|
|
|
|
|
|
|
|
|
if (ids.Length != existingEntitiesCount)
|
|
|
|
|
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
|
2024-03-20 12:52:28 +05:00
|
|
|
|
|
2024-04-15 10:38:41 +05:00
|
|
|
|
var entities = dbContext.Set<TEntity>().Where(e => ids.Contains(e.Id));
|
|
|
|
|
dbContext.Set<TEntity>().UpdateRange(entities);
|
|
|
|
|
return await dbContext.SaveChangesAsync(token);
|
2024-03-20 12:52:28 +05:00
|
|
|
|
}
|
2021-08-10 14:36:35 +05:00
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
/// <inheritdoc/>
|
2022-12-07 15:23:10 +05:00
|
|
|
|
public virtual Task<int> DeleteAsync(int id, CancellationToken token)
|
2021-08-10 14:36:35 +05:00
|
|
|
|
{
|
2022-06-06 15:43:47 +05:00
|
|
|
|
var entity = dbSet
|
|
|
|
|
.AsNoTracking()
|
2021-08-11 10:16:01 +05:00
|
|
|
|
.FirstOrDefault(e => e.Id == id);
|
2021-08-10 14:36:35 +05:00
|
|
|
|
if (entity == default)
|
2022-12-01 15:56:11 +05:00
|
|
|
|
return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound);
|
2024-04-08 09:17:17 +05:00
|
|
|
|
dbSet.Remove(entity);
|
2022-06-09 17:25:26 +05:00
|
|
|
|
var affected = dbContext.SaveChangesAsync(token);
|
|
|
|
|
return affected;
|
2021-08-10 14:36:35 +05:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-20 12:52:28 +05:00
|
|
|
|
public virtual async Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token)
|
|
|
|
|
{
|
2024-03-26 13:35:36 +05:00
|
|
|
|
if (!ids.Any())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
var countExistingEntities = await dbSet
|
|
|
|
|
.Where(d => ids.Contains(d.Id))
|
|
|
|
|
.CountAsync(token);
|
2024-03-20 12:52:28 +05:00
|
|
|
|
|
2024-03-26 13:35:36 +05:00
|
|
|
|
if (ids.Count() > countExistingEntities)
|
|
|
|
|
return ICrudRepository<TDto>.ErrorIdNotFound;
|
|
|
|
|
|
|
|
|
|
var entities = dbContext.Set<TEntity>().Where(e => ids.Contains(e.Id));
|
2024-04-08 09:17:17 +05:00
|
|
|
|
dbContext.Set<TEntity>().RemoveRange(entities);
|
|
|
|
|
return await dbContext.SaveChangesAsync(token);
|
2024-03-20 12:52:28 +05:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
protected virtual TDto Convert(TEntity src) => src.Adapt<TDto>();
|
2021-09-10 11:28:57 +05:00
|
|
|
|
|
2022-06-06 15:43:47 +05:00
|
|
|
|
protected virtual TEntity Convert(TDto src) => src.Adapt<TEntity>();
|
2021-08-10 14:36:35 +05:00
|
|
|
|
}
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2021-08-10 14:36:35 +05:00
|
|
|
|
}
|