using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Runtime.CompilerServices; 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 { /// /// 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: /// > /// > /// > /// /// /// /// public abstract class XBaseRepositoryService : IXBaseRepositoryService where TEntity : XBaseEntity where TDto : XBaseEntityDto { // #region Properties ... /// /// Mapper Instance ... /// public IMapper Mapper { get; } /// /// Repository Implementation for Data Manipulations ... /// public IXBaseRepository Repository { get; } /// /// 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 ... /// public MapperConfiguration MapperConfiguration { get; } #endregion // #region Constructor ... public XBaseRepositoryService( IXBaseRepository repository, IEnumerable mapperProfiles = null ) { // Repository = repository; // // Preparing Mapping Configurations ... MapperConfiguration = new MapperConfiguration(cfg => { // // Add Default Profiles ... // // Entity To Dto ... cfg.CreateMap() .ForMember(dest => dest.Deleted, opt => opt.Ignore()); cfg.CreateMap, XQueryResult>(); // // Dto to Entity ... cfg.CreateMap() .ForMember(dest => dest.Deleted, opt => opt.Ignore()); cfg.CreateMap, XQueryResult>(); // // 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 ... /// /// add a new Dto ... /// /// /// /// /// public async Task 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(item); // entity = await Repository.AddAsync( item: entity, saveChanges: saveChanges, cancellationToken: cancellationToken ); // result = Mapper.Map(entity); } catch { } // return result; } /// /// add or update a Dto (add if not exists/update if exists) ... /// /// /// /// /// public async Task 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(item); // entity = await Repository.AddOrUpdateAsync( item: entity, saveChanges: saveChanges, cancellationToken: cancellationToken ); // result = Mapper.Map(entity); } catch { } // return result; } /// /// add a range of new Dtos ... /// /// /// /// /// public async Task AddRangeAsync( IEnumerable 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>(items); // await Repository.AddRangeAsync( items: entities, saveChanges: saveChanges, cancellationToken: cancellationToken ); } catch { } } #endregion // #region Update ... /// /// Update an Dto values ... /// /// /// /// /// /// public async Task UpdateAsync( TKey id, TDto item, bool saveChanges = true, CancellationToken cancellationToken = default ) { // TDto result = null; // try { // var entity = Mapper.Map(item); // entity = await Repository.UpdateAsync( id: item.Id, item: entity, saveChanges: saveChanges, cancellationToken: cancellationToken ); // result = Mapper.Map(entity); } catch { } // return result; } /// /// Update a range of Dtos ... /// /// /// /// /// public async Task UpdateRangeAsync( IEnumerable items, bool saveChanges = true, CancellationToken cancellationToken = default ) { // // Validate ... var result = !items.IsNull() && items.HasChild(); if (!result) { return result; } // try { // var entitis = Mapper.Map>(items); // result = await Repository.UpdateRangeAsync( items: entitis, saveChanges: saveChanges, cancellationToken: cancellationToken ); } catch { result = false; } // return result; } #endregion // #region Remove ... /// /// remove an Dto by it's Id ... /// /// /// /// /// /// public async Task 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(entity); } catch { } // return result; } /// /// remove an Dto ... /// /// /// /// /// /// public async Task RemoveAsync( TDto item, bool softDelete = true, bool saveChanges = true, CancellationToken cancellationToken = default ) { // TDto result = null; // try { // var entity = Mapper.Map(item); // entity = await Repository.RemoveAsync( item: entity, softDelete: softDelete, saveChanges: saveChanges, cancellationToken: cancellationToken ); // result = Mapper.Map(entity); } catch { } // return result; } /// /// remove a range of exists Dtos ... /// /// /// /// /// /// public async Task RemoveRangeAsync( IEnumerable items, bool softDelete = true, bool saveChanges = true, CancellationToken cancellationToken = default ) { // // Validate ... var isValid = !items.IsNull() && items.HasChild(); if (!isValid) { return; } // var entities = Mapper.Map>(items); // try { // await Repository.RemoveRangeAsync( items: entities, softDelete: softDelete, saveChanges: saveChanges, cancellationToken: cancellationToken ); } catch { } } #endregion // #region Count ... /// /// count all exists Dtos ... /// /// /// /// public async Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await Repository.CountAsync( cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// count all exists Entities Pages by providing page size ... /// /// /// /// /// /// public async Task 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 ... /// /// Check a Dto exists or not ... /// /// /// /// /// public async Task 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 ... /// /// retrieve an Dto by it's Id ... /// /// /// /// /// /// public async Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> 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(entity); } catch { } // return result; } /// /// retrieve all exists Dtos ... /// /// /// /// /// /// public async Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // IEnumerable result = Enumerable.Empty(); // try { // var entities = await Repository.GetAllAsync( orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // result = Mapper.Map>(entities); } catch { } // return result; } /// /// retrieve all exists Dtos /// as Async Enumerable ... /// /// /// /// /// /// public async IAsyncEnumerable GetAllAsAsyncEnumerable( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, [EnumeratorCancellation] CancellationToken cancellationToken = default ) { // var entityEnumerable = Repository.GetAllAsAsyncEnumerable( orderBuilder: orderBuilder, includeBuilder: includeBuilder, ignoreSoftDeleteds: ignoreSoftDeleteds ); await foreach (var entity in entityEnumerable) { // if (cancellationToken.IsCancellationRequested) { yield break; } // var dto = Mapper.Map(entity); yield return dto; } } /// /// find an Dto by providing a Conditional Expression ... /// /// /// /// /// /// public async Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> 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(entity); } catch { } // return result; } /// /// find a collection of Dtos by proving a Conditional Expression ... /// /// /// /// /// /// /// public async Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // IEnumerable result = Enumerable.Empty(); // try { // var entities = await Repository.FindManyAsync( predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // result = Mapper.Map>(entities); } catch { } // return result; } /// /// retrieve Dtos based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// public async Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // XQueryResult result = null; // try { // var entityResult = await Repository.QueryAsync( query: query, predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // result = Mapper.Map>(entityResult); } catch { } // return result; } #endregion public virtual void Dispose() { } #endregion } }