DepartmentProject/DepartmentPortal/Common/CoreDatabase/AbstractGenerticEntityService.cs

268 lines
8.6 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 CoreDatabase.Models;
using Microsoft.EntityFrameworkCore;
using ToolsModule.BindingModels;
using ToolsModule.BusinessLogics;
using ToolsModule.Enums;
using ToolsModule.Interfaces;
using ToolsModule.Models;
using ToolsModule.ViewModels;
using System;
using System.Linq;
namespace CoreDatabase
{
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 OperationResultModel Create(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);
context.Set<T>().Add(entity);
context.SaveChanges();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(entity, true));
}
else
{
if (exsistEntity.IsDeleted)
{
exsistEntity = Mapper.MapToClass(model, exsistEntity, true);
exsistEntity.IsDeleted = false;
context.SaveChanges();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(exsistEntity, true));
}
else
{
return OperationResultModel.Error("Error:", "Элемент уже существует", ResultServiceStatusCode.ExsistItem);
}
}
}
public OperationResultModel Delete(G model)
{
using var context = DatabaseManager.GetContext;
using var transaction = context.Database.BeginTransaction();
try
{
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);
}
var result = AdditionalCheckingWhenDeleting(context, entity, model);
if (!result.IsSucceeded)
{
return result;
}
entity.IsDeleted = true;
entity.DateDelete = DateTime.Now;
context.SaveChanges();
AdditionalDeleting(context, entity, model);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
return OperationResultModel.Success(true);
}
public OperationResultModel Restore(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;
context.SaveChanges();
return OperationResultModel.Success(Mapper.MapToClass<T, E>(entity, true));
}
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
}
public OperationResultModel Read(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);
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 OperationResultModel Update(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);
context.SaveChanges();
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);
/// <summary>
/// Дополнительыне проверки, если требуется получать единичную запись но не по id
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
protected virtual bool AdditionalCheckForSingleGet(G model) => false;
/// <summary>
/// Получение единичной записи но не по id
/// </summary>
/// <param name="list"></param>
/// <param name="model"></param>
/// <returns></returns>
protected virtual T GetSingleRecord(IQueryable<T> list, G model) => null;
}
}