using System; using System.Linq; using xModels.Dtos; using System.Threading; using xCommons.Extensions; using xIdentityModels.Dtos; using xExceptions.Constants; using System.Threading.Tasks; using xIdentityModels.Models; using System.Linq.Expressions; using xDataService.Extensions; using System.Collections.Generic; using xIdentityModels.Extensions; using xIdentityHelper.Extensions; using Microsoft.EntityFrameworkCore; using System.Runtime.CompilerServices; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.ChangeTracking; namespace xIds.Providers { public partial class XApplicationProvider { // #region Application ... /// /// Add Specified Item ... /// /// /// /// /// public async Task AddApplicationAsync( XApplicationDto item, XUserClaimsInfoDto userInfo = null, CancellationToken cancellationToken = default ) { // // Validate ... if (!item.IsValidForAdd()) { XException.InvalidArgs.Throw(); } // // Permission ... if (userInfo.IsNullOrDefault()) { XException.NotAllowed.Throw(); } // item.OwnerId = userInfo.UserId; item.CreatedOn = DateTime.UtcNow; // var entity = item.MapConvert(); if (entity.Id.IsValidIntId()) { entity.Id = -1; } // var entry = await dbContext.Applications.AddAsync( entity: entity, cancellationToken: cancellationToken ); var changes = await dbContext.SaveChangesAsync(cancellationToken); // if ( changes <= 0 || entry.IsNull() || entry.Entity.IsNullOrDefault() ) { XException.ActionFailed.Throw(); } // var result = await EnrichAsync( source: entry.Entity, cancellationToken: cancellationToken ); return result; } /// /// Update Specified Item ... /// /// /// /// /// /// public async Task UpdateApplicationAsync( int id, XApplicationDto item, XUserClaimsInfoDto userInfo = null, CancellationToken cancellationToken = default ) { // // Validate ... if ( id != item.Id || !id.IsValidIntId() || item.IsNullOrDefault() || userInfo.IsNullOrDefault() ) { XException.InvalidArgs.Throw(); } // // Retrieve Exists Entity ... var exists = await dbContext.Applications .FirstOrDefaultAsync(x => x.Id == id && !x.Deleted); if (exists.IsNullOrDefault()) { XException.NotFound.Throw(); } // // Permission Checking ... if (!IsOwned(exists, userInfo)) { XException.NotAllowed.Throw(); } // // Update Data on Exists Entity ... exists = exists.UpdateData( updateWith: item, propertyWhiteList: [ nameof(XApplication.Name), nameof(XApplication.Type), nameof(XApplication.OwnerId), nameof(XApplication.IsActive), nameof(XApplication.CreatedOn), nameof(XApplication.UpdatedAt), nameof(XApplication.Description), ] ); // var entry = dbContext.Applications.Attach(exists); entry.State = EntityState.Modified; // var changes = await dbContext.SaveChangesAsync(cancellationToken); if ( changes <= 0 || entry.IsNull() || entry.Entity.IsNullOrDefault() ) { XException.ActionFailed.Throw(); } // var result = await EnrichAsync( source: entry.Entity, cancellationToken: cancellationToken ); return result; } /// /// Remove Specified Item ... /// /// /// /// /// /// public async Task RemoveApplicationAsync( int id, bool softDelete = true, XUserClaimsInfoDto userInfo = null, CancellationToken cancellationToken = default ) { // // Validate ... if ( !id.IsValidIntId() || userInfo.IsNullOrDefault() ) { XException.InvalidArgs.Throw(); } // // Retrieve Exists Entity ... var exists = await dbContext.Applications .FirstOrDefaultAsync(x => x.Id == id && !x.Deleted); if (exists.IsNullOrDefault()) { XException.NotFound.Throw(); } // // Permission Checking ... if (!IsOwned(exists, userInfo)) { XException.NotAllowed.Throw(); } // EntityEntry entry = null; if (softDelete) { // exists.Deleted = true; entry = dbContext.Applications.Update(exists); } else { entry = dbContext.Applications.Remove(exists); } // var changes = await dbContext.SaveChangesAsync(cancellationToken); if ( changes <= 0 || entry.IsNull() || entry.Entity.IsNull() ) { XException.ActionFailed.Throw(); } // var result = await EnrichAsync( source: entry.Entity, cancellationToken: cancellationToken ); return result; } /// /// Retrieve an Item by Providing it's ID ... /// /// /// /// /// /// /// public async Task GetApplicationAsync( int id, bool ignoreSoftDeleteds = true, XUserClaimsInfoDto userInfo = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // // Validate ... if (!id.IsValidIntId() || userInfo.IsNullOrDefault()) { XException.InvalidArgs.Throw(); } // // Prepare Condition ... Expression> predicate = x => x.OwnerId != userInfo.UserId || !ignoreSoftDeleteds || !x.Deleted; if (userInfo.IsAdmin()) { // predicate = x => !ignoreSoftDeleteds || !x.Deleted; } // // Retrieve Queryable ... var queryable = GetApplicationsQeryable( orderBuilder: null, predicate: predicate, includeBuilder: includeBuilder ); // var entity = await queryable.FirstOrDefaultAsync( predicate: x => x.Id == id, cancellationToken: cancellationToken ); // var result = await EnrichAsync( source: entity, cancellationToken: cancellationToken ); return result; } /// /// Retrieve all Items ... /// /// /// /// /// /// /// public async Task> GetAllApplicationAsync( bool ignoreSoftDeleteds = true, XUserClaimsInfoDto userInfo = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // // Validate ... if (userInfo.IsNullOrDefault()) { XException.InvalidArgs.Throw(); } // // Prepare Condition ... Expression> predicate = x => x.OwnerId == userInfo.UserId && (!ignoreSoftDeleteds || !x.Deleted); if (userInfo.IsAdmin()) { // predicate = x => !ignoreSoftDeleteds || !x.Deleted; } // // Retrieve Queryable ... var queryable = GetApplicationsQeryable( predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder ); // var items = await queryable.ToListAsync(cancellationToken); var result = await EnrichRangeAsync( sources: items, cancellationToken: cancellationToken ); // return result; } /// /// Retrieve all Items as Async Enumerable ... /// /// /// /// /// /// /// public async IAsyncEnumerable GetAllApplicationAsAsyncEnumerable( bool ignoreSoftDeleteds = true, XUserClaimsInfoDto userInfo = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, [EnumeratorCancellation] CancellationToken cancellationToken = default ) { // // Validate ... if (userInfo.IsNullOrDefault()) { XException.InvalidArgs.Throw(); } // // Prepare Condition ... Expression> predicate = x => x.OwnerId == userInfo.UserId && (!ignoreSoftDeleteds || !x.Deleted); if (userInfo.IsAdmin()) { // predicate = x => !ignoreSoftDeleteds || !x.Deleted; } // // Retrieve Queryable ... var queryable = GetApplicationsQeryable( predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder ); // var enumerator = queryable.AsAsyncEnumerable(); await foreach (var item in enumerator) { // // Handle Cancellation Token ... if (cancellationToken.IsCancellationRequested) { yield break; } // var dto = await EnrichAsync( source: item, cancellationToken: cancellationToken ); yield return dto; } } /// /// Find an Item By Providing a Conditional Expression ... /// /// /// /// /// /// /// public async Task FindOneApplicationAsync( Expression> predicate, bool ignoreSoftDeleteds = true, XUserClaimsInfoDto userInfo = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // // Validate ... if (userInfo.IsNullOrDefault()) { XException.InvalidArgs.Throw(); } // Expression> _predicate = x => !ignoreSoftDeleteds || !x.Deleted; if (!userInfo.IsAdmin()) { _predicate = x => x.OwnerId == userInfo.UserId && (!ignoreSoftDeleteds || !x.Deleted); } // var queryable = GetApplicationsQeryable( orderBuilder: null, predicate: _predicate, includeBuilder: includeBuilder ); // var entity = (await queryable .ToListAsync(cancellationToken)) .FirstOrDefault(x => predicate.Compile()(x)); // var result = await EnrichAsync( source: entity, cancellationToken: cancellationToken ); return result; } /// /// Find a Collection of Items By Providing a Conditional Expression ... /// /// /// /// /// /// /// /// public async Task> FindManyApplicationAsync( Expression> predicate, bool ignoreSoftDeleteds = true, XUserClaimsInfoDto userInfo = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // // Validate ... if (userInfo.IsNullOrDefault()) { XException.InvalidArgs.Throw(); } // Expression> _predicate = x => !ignoreSoftDeleteds || !x.Deleted; if (!userInfo.IsAdmin()) { _predicate = x => x.OwnerId == userInfo.UserId && (!ignoreSoftDeleteds || !x.Deleted); } // var queryable = GetApplicationsQeryable( orderBuilder: null, predicate: _predicate, includeBuilder: includeBuilder ); // var entities = (await queryable .ToListAsync(cancellationToken)) .Where(x => predicate.Compile()(x)); // var result = await EnrichRangeAsync( sources: entities, cancellationToken: cancellationToken ); return result; } /// /// Retrieve Items based on XQuery Pagination Structure ... /// /// /// /// /// /// /// /// /// public async Task> QueryApplicationAsync( XQuery query, bool ignoreSoftDeleteds = true, XUserClaimsInfoDto userInfo = null, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // // Normalize Query ... query = NormalizeQuery(query, configuration); // var items = await GetAllApplicationAsync( userInfo: userInfo, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); var totalItemsCount = items.Count(); // // Apply Filter ... if (!query.Filter.IsNullOrEmpty()) { // items = items .ApplyFilter(query.Filter); } int filteredItemsCount = items.Count(); // // Count Pages ... var totalPagesCount = query.CountPages(totalItemsCount); var filteredPagesCount = query.CountPages(filteredItemsCount); // // Apply Paging and Sorting ... if (totalItemsCount > 0 && filteredItemsCount > 0 ) { // // Apply Sorting ... items = items .ToList() .ApplySorting( query.SortBy, query.IsAscending ); // // Apply Paging ... items = items .ToList() .ApplyPaging( query.Page, query.PageSize ); } // // Prepare Result ... var result = new XQueryResult { Page = query.Page, Items = [.. items], PageSize = query.PageSize, TotalPages = totalPagesCount, TotalItems = totalItemsCount, TotalFilteredPages = filteredPagesCount, TotalFilteredItems = filteredItemsCount }; // return result; } #endregion } }