DepartmentProject/DepartmentPortal/Common/DatabaseCore/AbstractGenerticEntityService.cs

262 lines
8.4 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 DatabaseCore.Models;
using Microsoft.EntityFrameworkCore;
using ModuleTools.BindingModels;
using ModuleTools.BusinessLogics;
using ModuleTools.Enums;
using ModuleTools.Interfaces;
using ModuleTools.Models;
using ModuleTools.ViewModels;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace DatabaseCore
{
public abstract class AbstractGenerticEntityService<G, S, T, L, E> : IGenerticEntityService<G, S>
where G : GetBindingModel
where S : SetBindingModel
where T : BaseEntity
where L : ListViewModel<E>, new()
where E : ElementViewModel
{
public async Task<OperationResultModel> CreateAsync(S model)
{
using var context = DatabaseManager.GetContext;
var result = AdditionalCheckingWhenAdding(context, model);
if (!result.IsSucceeded)
{
return result;
}
var exsistEntity = GetUniqueEntity(model, context);
if (exsistEntity == null)
{
var entity = Mapper.MapToClass<S, T>(model, true);
await context.Set<T>().AddAsync(entity);
await context.SaveChangesAsync();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(entity, true));
}
else
{
if (exsistEntity.IsDeleted)
{
exsistEntity = Mapper.MapToClass(model, exsistEntity, true);
exsistEntity.IsDeleted = false;
await context.SaveChangesAsync();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(exsistEntity, true));
}
else
{
return OperationResultModel.Error("Error:", "Элемент уже существует", ResultServiceStatusCode.ExsistItem);
}
}
}
public async Task<OperationResultModel> DeleteAsync(G model)
{
using var context = DatabaseManager.GetContext;
using var transaction = context.Database.BeginTransaction();
try
{
var entity = await context.Set<T>().FirstOrDefaultAsync(x => x.Id == model.Id);
if (entity == null)
{
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
}
else if (entity.IsDeleted)
{
return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
}
var result = AdditionalCheckingWhenDeleting(context, entity, model);
if (!result.IsSucceeded)
{
return result;
}
entity.IsDeleted = true;
entity.DateDelete = DateTime.Now;
await context.SaveChangesAsync();
AdditionalDeleting(context, entity, model);
await transaction.CommitAsync();
}
catch (Exception)
{
await transaction.RollbackAsync();
throw;
}
return OperationResultModel.Success(true);
}
public async Task<OperationResultModel> RestoreAsync(G model)
{
if (model.Id.HasValue || AdditionalCheckForSingleGet(model))
{
using var context = DatabaseManager.GetContext;
var entity = model.Id.HasValue ? IncludingWhenReading(context.Set<T>().AsQueryable()).FirstOrDefault(x => x.Id == model.Id.Value)
: GetSingleRecord(context.Set<T>().AsQueryable(), model);
if (entity == null)
{
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
}
else if (!entity.IsDeleted)
{
return OperationResultModel.Error("Error:", "Элемент не был удален", ResultServiceStatusCode.ExsistItem);
}
entity.IsDeleted = false;
await context.SaveChangesAsync();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(entity, true));
}
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
}
public async Task<OperationResultModel> ReadAsync(G model)
{
int countPages = 0;
using var context = DatabaseManager.GetContext;
// для одной записи
if (model.Id.HasValue || AdditionalCheckForSingleGet(model))
{
var entity = model.Id.HasValue ? IncludingWhenReading(context.Set<T>().AsQueryable()).FirstOrDefault(x => x.Id == model.Id.Value)
: GetSingleRecord(context.Set<T>().AsQueryable(), model);
if (entity == null)
{
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
}
if (entity.IsDeleted)
{
return OperationResultModel.Error("Error:", "Элемент удален", ResultServiceStatusCode.WasDelete);
}
return OperationResultModel.Success(Mapper.MapToClass<T, E>(entity, model.HaveRight));
}
var query = context.Set<T>().Where(x => !x.IsDeleted).AsQueryable();
query = AdditionalCheckingWhenReadingList(query, model);
query = OrderingWhenReading(query);
query = IncludingWhenReading(query);
return await Task.Run(() =>
{
if (model.PageNumber.HasValue && model.PageSize.HasValue)
{
countPages = (int)Math.Ceiling((double)query.Count() / model.PageSize.Value);
query = query
.Skip(model.PageSize.Value * model.PageNumber.Value)
.Take(model.PageSize.Value);
}
var result = new L
{
MaxCount = countPages,
List = query.Select(x => Mapper.MapToClass<T, E>(x, model.HaveRight)).ToList()
};
return OperationResultModel.Success(result);
});
}
public async Task<OperationResultModel> UpdateAsync(S model)
{
using var context = DatabaseManager.GetContext;
var result = AdditionalCheckingWhenUpdateing(context, model);
if (!result.IsSucceeded)
{
return result;
}
var exsistEntity = GetUniqueEntity(model, context);
if (exsistEntity != null)
{
return OperationResultModel.Error("Error:", "Существует запись с такими значениями", ResultServiceStatusCode.ExsistItem);
}
var entity = context.Set<T>().FirstOrDefault(x => x.Id == model.Id);
if (entity == null)
{
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
}
else if (entity.IsDeleted)
{
return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
}
entity = Mapper.MapToClass(model, entity, true);
await context.SaveChangesAsync();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(entity, true));
}
/// <summary>
/// Поиск записи с уникальными значениями
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
protected abstract T GetUniqueEntity(S model, DbContext context);
/// <summary>
/// Возможные дополнительные проверки при добавлении
/// </summary>
/// <param name="context"></param>
/// <param name="model"></param>
/// <returns></returns>
protected abstract OperationResultModel AdditionalCheckingWhenAdding(DbContext context, S model);
/// <summary>
/// Возможные дополнительные проверки при удалении
/// </summary>
/// <param name="context"></param>
/// <param name="model"></param>
/// <returns></returns>
protected abstract OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, T entity, G model);
/// <summary>
/// Добавление дополнительных фильтров
/// </summary>
/// <param name="query"></param>
/// <param name="model"></param>
/// <returns></returns>
protected abstract IQueryable<T> AdditionalCheckingWhenReadingList(IQueryable<T> query, G model);
/// <summary>
/// Возможные дополнительные проверки модели при изменении
/// </summary>
/// <param name="model"></param>
protected abstract OperationResultModel AdditionalCheckingWhenUpdateing(DbContext context, S model);
/// <summary>
/// Дополнительные удаления зависимых сущностей
/// </summary>
/// <param name="model"></param>
protected abstract void AdditionalDeleting(DbContext context, T entity, G model);
/// <summary>
/// Установка сортировок
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
protected abstract IQueryable<T> OrderingWhenReading(IQueryable<T> query);
/// <summary>
/// Добавление Include
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
protected abstract IQueryable<T> IncludingWhenReading(IQueryable<T> query);
protected virtual bool AdditionalCheckForSingleGet(G model) => false;
protected virtual T GetSingleRecord(IQueryable<T> list, G model) => null;
}
}