Files
xDataService/Providers/XBaseRepositoryService.cs
T
2026-05-04 00:37:06 +03:30

745 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.EntityFrameworkCore.Query;
using xCommons.Extensions;
using xDataService.Interfaces;
using xModels.Base;
using xModels.Dtos;
namespace xDataService.Providers
{
/// <summary>
/// a Base Repository Service Implementation which Use a Repository Patterns Implementatin
/// and provides Data Manipulation Methods using Dtos instead of Entities ...
///
/// it can be use of following Repository Patterns Implementation:
/// <see cref="XBaseEFRepository"/>>
/// <see cref="XBaseMongoRepository"/>>
/// <see cref="XBaseInMemoryRepository"/>>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class XBaseRepositoryService<TEntity, TDto, TKey> : IXBaseRepositoryService<TEntity, TDto, TKey>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
{
//
#region Properties ...
/// <summary>
/// Mapper Instance ...
/// </summary>
public IMapper Mapper { get; }
/// <summary>
/// Repository Implementation for Data Manipulations ...
/// </summary>
public IXBaseRepository<TEntity, TKey> Repository { get; }
/// <summary>
/// Mapping Profile Configuration ...
///
/// this Configuration used for Mapping TEntity to Dto and reverse ...
/// default mapping prepared on Constructing time, other custom maps
/// must handled manually if required ...
/// </summary>
public MapperConfiguration MapperConfiguration { get; }
#endregion
//
#region Constructor ...
public XBaseRepositoryService(
IXBaseRepository<TEntity, TKey> repository,
IEnumerable<Profile> mapperProfiles = null
)
{
//
Repository = repository;
//
// Preparing Mapping Configurations ...
MapperConfiguration = new MapperConfiguration(cfg =>
{
//
// Add Default Profiles ...
//
// Entity To Dto ...
cfg.CreateMap<TEntity, TDto>()
.ForMember(dest => dest.Deleted, opt => opt.Ignore());
//
// Dto to Entity ...
cfg.CreateMap<TDto, TEntity>()
.ForMember(dest => dest.Deleted, opt => opt.Ignore());
//
// Add Provided Profiles if Provided ...
// if Same Profiles Provided, here resolved ...
if (!mapperProfiles.IsNull() &&
mapperProfiles.HasChild())
{
cfg.AddProfiles(mapperProfiles);
}
});
//
// Make Mapper Instance using prepared Configuration ...
Mapper = MapperConfiguration.CreateMapper();
}
#endregion
//
#region Actions ...
//
#region Add ...
/// <summary>
/// add a new Dto ...
/// </summary>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> AddAsync(
TDto item,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
// Validate ...
bool isValid = !item.IsNull();
if (!isValid)
{
return result;
}
//
try
{
//
var entity = Mapper.Map<TEntity>(item);
//
entity = await Repository.AddAsync(
item: entity,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// add or update a Dto (add if not exists/update if exists) ...
/// </summary>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> AddOrUpdateAsync(
TDto item,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
// Validate ...
bool isValid = !item.IsNull();
if (!isValid)
{
return result;
}
//
try
{
//
var entity = Mapper.Map<TEntity>(item);
//
entity = await Repository.AddOrUpdateAsync(
item: entity,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// add a range of new Dtos ...
/// </summary>
/// <param name="items"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task AddRangeAsync(
IEnumerable<TDto> items,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
// Validate ...
bool isValid =
!items.IsNull() &&
items.HasChild();
if (!isValid)
{
return;
}
//
try
{
//
var entities = Mapper.Map<IEnumerable<TEntity>>(items);
//
await Repository.AddRangeAsync(
items: entities,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
}
catch
{ }
}
#endregion
//
#region Update ...
/// <summary>
/// Update an Dto values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> UpdateAsync(
TKey id,
TDto item,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
try
{
//
var entity = Mapper.Map<TEntity>(item);
//
entity = await Repository.UpdateAsync(
id: item.Id,
item: entity,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// Update a range of Dtos ...
/// </summary>
/// <param name="items"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> UpdateRangeAsync(
IEnumerable<TDto> items,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var result =
!items.IsNull() &&
items.HasChild();
if (!result)
{
return result;
}
//
try
{
//
var entitis = Mapper.Map<IEnumerable<TEntity>>(items);
//
result = await Repository.UpdateRangeAsync(
items: entitis,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
}
catch
{
result = false;
}
//
return result;
}
#endregion
//
#region Remove ...
/// <summary>
/// remove an Dto by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="softDelete"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> RemoveAsync(
TKey id,
bool softDelete = true,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
try
{
//
var entity = await Repository.RemoveAsync(
id: id,
softDelete: softDelete,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// remove an Dto ...
/// </summary>
/// <param name="item"></param>
/// <param name="softDelete"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> RemoveAsync(
TDto item,
bool softDelete = true,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
try
{
//
var entity = Mapper.Map<TEntity>(item);
//
entity = await Repository.RemoveAsync(
item: entity,
softDelete: softDelete,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// remove a range of exists Dtos ...
/// </summary>
/// <param name="items"></param>
/// <param name="softDelete"></param>
/// <param name="saveChanges"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task RemoveRangeAsync(
IEnumerable<TDto> items,
bool softDelete = true,
bool saveChanges = true,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid =
!items.IsNull() &&
items.HasChild();
if (!isValid)
{
return;
}
//
var entities = Mapper.Map<IEnumerable<TEntity>>(items);
//
try
{
//
await Repository.RemoveRangeAsync(
items: entities,
softDelete: softDelete,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
}
catch
{ }
}
#endregion
//
#region Count ...
/// <summary>
/// count all exists Dtos ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<int> CountAsync(
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.CountAsync(
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// count all exists Entities Pages by providing page size ...
/// </summary>
/// <param name="pageSize"></param>
/// <param name="totalItems"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<int> PagesCountAsync(
int pageSize,
int? totalItems = null,
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.PagesCountAsync(
pageSize: pageSize,
totalItems: totalItems,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
#endregion
//
#region Exists ...
/// <summary>
/// Check a Dto exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> IsExistsAsync(
TKey id,
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.IsExistsAsync(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
#endregion
//
#region Retrieve ...
/// <summary>
/// retrieve an Dto by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> GetAsync(
TKey id,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
try
{
//
var entity = await Repository.GetAsync(
id: id,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// retrieve all exists Dtos ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<TDto>> GetAllAsync(
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
IEnumerable<TDto> result = Enumerable.Empty<TDto>();
//
try
{
//
var entities = await Repository.GetAllAsync(
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
result = Mapper.Map<IEnumerable<TDto>>(entities);
}
catch
{ }
//
return result;
}
/// <summary>
/// find an Dto by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> FindOneAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
TDto result = null;
//
try
{
//
var entity = await Repository.FindOneAsync(
predicate: predicate,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
result = Mapper.Map<TDto>(entity);
}
catch
{ }
//
return result;
}
/// <summary>
/// find a collection of Dtos by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<TDto>> FindManyAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
IEnumerable<TDto> result = Enumerable.Empty<TDto>();
//
try
{
//
var entities = await Repository.FindManyAsync(
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
result = Mapper.Map<IEnumerable<TDto>>(entities);
}
catch
{ }
//
return result;
}
/// <summary>
/// retrieve Dtos based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<TDto>> QueryAsync(
XQuery query,
bool ignoreSoftDeleteds = true,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
XQueryResult<TDto> result = null;
//
try
{
//
var entityResult = await Repository.QueryAsync(
query: query,
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
result = Mapper.Map<XQueryResult<TDto>>(entityResult);
}
catch
{ }
//
return result;
}
#endregion
public virtual void Dispose()
{ }
#endregion
}
}