Files
xCategoryService/Providers/XSubCategoryProvider.cs
T

1401 lines
46 KiB
C#

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 xCategoryService.Interfaces;
using xCategoryService.Interfaces.Dtos;
using xCategoryService.Models.Dtos;
using xCategoryService.Models.Entities;
using xCategoryService.Providers.Dtos;
using xCommons.Configurations;
using xCommons.Extensions;
using xDataService.Configuration;
using xExceptions.Constants;
using xIdentityModels.Models;
using xModels.Dtos;
using xDataService.Extensions;
using xPushService.Constants;
using xPushService.Providers;
namespace xCategoryService.Providers
{
public class XSubCategoryProvider : XBaseProvided<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>, IXSubCategoryProvider
{
private readonly XAppConfiguration appConfiguration;
private readonly IXCategoryProvider categoryProvider;
private readonly IXSubCategoryServiceProvider provider;
private readonly XDataServiceConfiguration dataServiceConfiguration;
private readonly IXSubCategoryTitleResourceProvider titleResourceProvider;
private readonly IXSubCategoryDescriptionResourceProvider descriptionResourceProvider;
public XSubCategoryProvider(
XAppConfiguration appConfiguration,
IXCategoryProvider categoryProvider,
IXSubCategoryServiceProvider provider,
XDataServiceConfiguration dataServiceConfiguration,
IXSubCategoryTitleResourceProvider titleResourceProvider,
IXSubCategoryDescriptionResourceProvider descriptionResourceProvider
) : base(
provider,
permittedRoles: new string[] { }
)
{
this.provider = provider;
this.appConfiguration = appConfiguration;
this.categoryProvider = categoryProvider;
this.titleResourceProvider = titleResourceProvider;
this.dataServiceConfiguration = dataServiceConfiguration;
this.descriptionResourceProvider = descriptionResourceProvider;
}
//
#region Overrides ...
public override bool IsOwned(
XSubCategoryDto item,
XUserClaimsInfoDto userInfo
)
{
return !item.IsNullOrDefault();
}
public override bool IsOwned(
XSubCategory item,
XUserClaimsInfoDto userInfo
)
{
return !item.IsNullOrDefault();
}
#endregion
//
#region Actions ...
/// <summary>
/// Check Has Specified Locale or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> HasLocale(
int id,
string language,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid =
id.IsValidIntId() &&
!language.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Retrieve Resource ...
var resource = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
// Check Result ...
var result =
!resource.IsNullOrDefault() &&
resource.Titles.Locales
.Any(x => x.Language
.Equals(language, System.StringComparison.InvariantCultureIgnoreCase));
//
return result;
}
/// <summary>
/// Load an Item by all of it's Related Translations ...
/// </summary>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> GetResource(
int id,
CancellationToken cancellationToken = default
)
{
//
var item = await Get(
id: id,
includeBuilder: null,
cancellationToken: cancellationToken
);
var titleResource = await titleResourceProvider.GetResource(
identifier: id,
cancellationToken: cancellationToken
);
var descriptionResource = await descriptionResourceProvider.GetResource(
identifier: id,
cancellationToken: cancellationToken
);
//
// Reading Category Resource ...
XCategoryResourceDto categoryResourceDto = null;
var categoryDto = await categoryProvider.GetReference(
providedForId: id,
cancellationToken: cancellationToken
);
if (!categoryDto.IsNullOrDefault())
{
categoryResourceDto = await categoryProvider.GetResource(
id: categoryDto.Id,
cancellationToken: cancellationToken
);
}
//
var result = new XSubCategoryResourceDto
{
Item = item,
Titles = titleResource,
Category = categoryResourceDto,
Descriptions = descriptionResource
};
//
return result;
}
/// <summary>
/// Add an Item for Specified Language ...
/// </summary>
/// <param name="item"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> Add(
XSubCategoryDto item,
string language = null,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Normalize ...
language =
!language.IsNullOrEmpty()
? language
: appConfiguration.DefaultLanguage;
//
// Validate ...
var isValid = !item.IsNullOrDefault();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Permission ...
isValid = HasPermision(userInfo);
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
var id = -1;
try
{
//
var title = item.Title;
var description = item.Description;
//
// Add Item Pure for ID Generating ...
item = await base.Add(
item: item,
userInfo: userInfo,
connectionId: null, // Since here We dont want notification ...
cancellationToken: cancellationToken
);
isValid = !item.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
id = item.Id;
var titleResource = await titleResourceProvider
.AddOrUpdateLocale(
identifier: id,
locale: new XLocaleResourceDto
{
Value = title,
Language = language
},
connectionId: connectionId,
cancellationToken: cancellationToken
);
var descriptionResource = await descriptionResourceProvider
.AddOrUpdateLocale(
identifier: id,
locale: new XLocaleResourceDto
{
Value = description,
Language = language
},
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
// Update Category Dto ...
item.Title = titleResource.Resource;
item.Description = descriptionResource.Resource;
item = await base.Update(
id: id,
item: item,
userInfo: userInfo,
connectionId: null,
cancellationToken: cancellationToken
);
}
catch
{
XException.InvalidArgs.Throw();
}
//
// Validate Id ...
isValid = id.IsValidIntId();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Retrieve Category Resourv=ce ...
var result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
// Sending Push Notification ...
isValid =
isValid &&
!result.IsNullOrDefault();
if (isValid)
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Add Item by it's Locales and Reference ...
/// </summary>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> AddResource(
XSubCategoryResourceDto item,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid =
!item.IsNullOrDefault() &&
!item.Titles.IsNullOrDefault() &&
item.Titles.Locales.HasChild() &&
!item.Titles.Locales.Any(tl =>
tl.Value.IsNullOrEmpty() ||
tl.Language.IsNullOrEmpty());
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
if (item.Item.IsNullOrDefault())
{
item.Item = new XSubCategoryDto();
}
//
// Check Permission ...
isValid = HasPermision(userInfo);
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
var id = -1;
try
{
//
// Handle Category Generation ...
if (!item.Category.IsNullOrDefault())
{
//
// Handle Category ...
try
{
// Try to Add Category ...
item.Category = await categoryProvider.Refresh(
resource: item.Category,
userInfo: userInfo,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
catch { }
}
//
// Add SubCategory for ID Generation ...
item.Item = await base.Add(
item: item.Item,
userInfo: userInfo,
connectionId: null, // Since here We dont want notification ...
cancellationToken: cancellationToken
);
isValid = !item.Item.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
id = item.Item.Id;
//
foreach (var il in item.Titles.Locales)
{
//
var title = il.Value;
var language = il.Language;
//
var descriptionItem =
item.Descriptions.IsNullOrDefault() ||
!item.Descriptions.Locales.HasChild()
? null
: item.Descriptions.Locales
.FirstOrDefault(ides =>
ides.Language
.Equals(
language,
StringComparison.InvariantCultureIgnoreCase));
var description =
descriptionItem.IsNullOrDefault()
? string.Empty
: descriptionItem.Value;
//
// Try to Add Resources ...
var titleResource = await titleResourceProvider
.AddOrUpdateLocale(
identifier: id,
locale: new XLocaleResourceDto
{
Value = title,
Language = language
},
connectionId: connectionId,
cancellationToken: cancellationToken
);
var descriptionResource = await descriptionResourceProvider
.AddOrUpdateLocale(
identifier: id,
locale: new XLocaleResourceDto
{
Value = description,
Language = language
},
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
// Update Category Dto if not ...
if (item.Item.Title.IsNullOrEmpty() ||
!item.Item.Title
.Equals(
titleResource.Resource,
StringComparison.InvariantCultureIgnoreCase)
)
{
//
item.Item.Title = titleResource.Resource;
item.Item.Description = descriptionResource.Resource;
item.Item = await base.Update(
id: id,
item: item.Item,
userInfo: userInfo,
connectionId: null,
cancellationToken: cancellationToken
);
}
}
}
catch
{
XException.InvalidArgs.Throw();
}
//
// Validate Id ...
isValid = id.IsValidIntId();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Add Resource Reference to Category ...
isValid = await categoryProvider.AddReference(
providedForId: id,
connectionId: null,
model: item.Category.Item,
cancellationToken: cancellationToken
);
//
// Retrieve Category Resourv=ce ...
var result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
// Sending Push Notification ...
isValid =
isValid &&
!result.IsNullOrDefault();
if (isValid)
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Remove Item for Specified Language ...
/// </summary>
/// <param name="id"></param>
/// <param name="language">if null, Remove All</param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> Remove(
int id,
string language = null,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid = id.IsValidIntId();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Item Exists ...
isValid = await IsExists(
id: id,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Validate Locale if Provided ...
isValid =
language.IsNullOrEmpty() ||
await HasLocale(
id: id,
language: language,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
if (language.IsNullOrEmpty())
{
//
// Remove All ...
//
// Titles ...
await titleResourceProvider.RemoveLocales(
identifier: id,
connectionId: null,
cancellationToken: cancellationToken
);
//
// Descriptions ...
await descriptionResourceProvider.RemoveLocales(
identifier: id,
connectionId: null,
cancellationToken: cancellationToken
);
//
// Remove Entity ...
await provider.RemoveAsync(
id: id,
softDelete: false,
saveChanges: true,
connectionId: null,
cancellationToken: cancellationToken
);
//
isValid = true;
result.Titles.Locales = [];
result.Descriptions.Locales = [];
}
else
{
//
// Remove Only One Locale, and if there is one, Remove all ...
//
// Remove Title if Exists ...
isValid = await titleResourceProvider.HasLocale(
identifier: id,
language: language,
cancellationToken: cancellationToken
);
if (isValid)
{
//
await titleResourceProvider.RemoveLocale(
identifier: id,
language: language,
connectionId: null,
cancellationToken: cancellationToken
);
}
//
// Remove Description if Exists ...
isValid = await descriptionResourceProvider.HasLocale(
identifier: id,
language: language,
cancellationToken: cancellationToken
);
if (isValid)
{
//
await descriptionResourceProvider.RemoveLocale(
identifier: id,
language: language,
connectionId: null,
cancellationToken: cancellationToken
);
}
//
// Retrieve Resource ...
result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
// Check Has Locales ...
isValid = result.Titles.Locales.HasChild();
if (!isValid)
{
//
// Remove Item ...
await provider.RemoveAsync(
id: id,
softDelete: false,
saveChanges: true,
connectionId: null,
cancellationToken: cancellationToken
);
//
result.Titles.Locales = [];
result.Descriptions.Locales = [];
}
//
isValid = true;
}
//
if (isValid)
{
//
// Send Push ...
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action:
result.Titles.Locales.HasChild()
? "DeleteLocale"
: XBaseEntityHubAction.Delete.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Update an Item for Specified Language ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> Update(
int id,
XSubCategoryDto item,
string language = null,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid =
id.IsValidIntId() &&
!item.IsNullOrDefault() &&
!language.IsNullOrEmpty() &&
!item.Title.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Category Exists ...
isValid = await IsExists(
id: id,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Check Locale Exists ...
isValid = await HasLocale(
id: id,
language: language,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Retrieve Category Dto for Validate Owining ...
var dto = await Get(
id: id,
includeBuilder: null,
cancellationToken: cancellationToken
);
//
// Check Permission ...
isValid =
!dto.IsNullOrDefault() &&
!userInfo.IsNullOrDefault() &&
(IsOwned(
item: dto,
userInfo: userInfo
) || HasPermision(userInfo));
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
// Retrieve Exists Item Resource ...
var resource = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
var titleUpdated = false;
var descriptionUpdated = false;
//
// Update Title ...
resource.Titles.Locales
.ToList()
.ForEach(tl =>
{
//
if (tl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
{
//
titleUpdated = true;
tl.Value = item.Title;
}
});
//
// Update Description ...
resource.Descriptions.Locales
.ToList()
.ForEach(dl =>
{
//
if (dl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
{
//
descriptionUpdated = true;
dl.Value = item.Description;
}
});
//
// Validate Title and Description Updated ...
isValid = titleUpdated && descriptionUpdated;
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
resource = await Refresh(
resource: resource,
userInfo: userInfo,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return resource;
}
/// <summary>
/// Refresh a Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> Refresh(
XSubCategoryResourceDto resource,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
var isValid =
!resource.IsNull();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Permission ...
isValid = HasPermision(userInfo);
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
var id = -1;
var isDelete = false;
XSubCategoryResourceDto result = null;
//
// Check Item Exists ...
XSubCategoryDto dto =
(resource.Item.IsNullOrDefault() ||
!resource.Item.Id.IsValidIntId())
? null
: await Get(
id: resource.Item.Id,
includeBuilder: null,
cancellationToken: cancellationToken
);
var isExists = !dto.IsNullOrDefault();
//
// Do Referesh Based on Existance ...
var isNew =
!isExists &&
(resource.Item.IsNullOrDefault() ||
!resource.Item.Id.IsValidIntId());
if (isNew)
{
//
// Add ...
// In this Senario, for Add a Category by Providing Resource
// the item must clean, either Title and Description, and tge Locales Provided by Resource
// ust Contains Values ...
// the Add Starts by Titles and only Items Add Which has Titles, since Title is Mandatory
// and Description is Optional ...
isValid =
//
// Resource ...
(resource.Item.IsNullOrDefault() ||
(!resource.Item.Id.IsValidIntId() &&
resource.Item.Title.IsNullOrEmpty() &&
resource.Item.Description.IsNullOrEmpty())) &&
//
// Titles ...
!resource.Titles.IsNullOrDefault() &&
resource.Titles.Locales.HasChild();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Add Temp Category ...
var unique = Guid.NewGuid();
var temp = new XSubCategoryDto
{
Title = $"TmpT_{unique}",
Description = $"TmpD_{unique}",
};
temp = await provider.AddAsync(
item: temp,
saveChanges: true,
connectionId: null,
cancellationToken: cancellationToken
);
isValid =
!temp.IsNullOrDefault() &&
temp.Id.IsValidIntId();
if (!isValid)
{
XException.ActionFailed.Throw();
}
id = temp.Id;
//
// Update Title and Description ...
var titleResource = titleResourceProvider.GetResourceTitle(id);
var descriptionResource = descriptionResourceProvider.GetResourceTitle(id);
temp.Title = titleResource;
temp.Description = descriptionResource;
temp = await provider.UpdateAsync(
id: id,
item: temp,
saveChanges: true,
connectionId: null,
cancellationToken: cancellationToken
);
//
// Loop through Titles ...
foreach (var locale in resource.Titles.Locales)
{
//
// Add Or Update Locale ...
await titleResourceProvider.AddOrUpdateLocale(
locale: locale,
identifier: id,
connectionId: null,
cancellationToken: cancellationToken
);
var desLocale = resource.Descriptions.Locales.FirstOrDefault(
dl =>
dl.Language == locale.Language);
if (!desLocale.IsNullOrDefault())
{
//
// Add Descriptions ...
await descriptionResourceProvider.AddOrUpdateLocale(
identifier: id,
locale: desLocale,
connectionId: null,
cancellationToken: cancellationToken
);
}
}
}
else if (isExists)
{
//
// Re State ...
id = resource.Item.Id;
//
// Try to Refresh Resource State ...
//
// Check Delete ...
isDelete = !resource.Titles.Locales.HasChild();
if (isDelete)
{
//
// Handle Delete ...
await Remove(
id: id,
language: null,
userInfo: userInfo,
connectionId: null,
cancellationToken: cancellationToken
);
}
else
{
//
// Handle Update ...
result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
#region Remove ...
//
// Titles ...
var removeTitles = result.Titles.Locales.Where(
l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
);
foreach (var locale in removeTitles)
{
//
await titleResourceProvider.RemoveLocale(
identifier: id,
connectionId: null,
language: locale.Language,
cancellationToken: cancellationToken
);
}
//
// Descriptions ...
var removeDescriptions = result.Descriptions.Locales.Where(
l => !resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
);
foreach (var locale in removeDescriptions)
{
//
await descriptionResourceProvider.RemoveLocale(
identifier: id,
connectionId: null,
language: locale.Language,
cancellationToken: cancellationToken
);
}
#endregion
//
#region Update ...
//
// Titles ...
var updateTitles = result.Titles.Locales.Where(
l => resource.Titles.Locales.Any(r =>
r.Value
.Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) &&
r.Language
.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase)
)
);
foreach (var locale in updateTitles)
{
//
await titleResourceProvider.AddOrUpdateLocale(
identifier: id,
locale: locale,
connectionId: null,
cancellationToken: cancellationToken
);
}
//
// Descriptions ...
var updateDescriptions = result.Descriptions.Locales.Where(
l => resource.Descriptions.Locales.Any(r =>
r.Value
.Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) &&
r.Language
.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
);
foreach (var locale in updateDescriptions)
{
//
await descriptionResourceProvider.AddOrUpdateLocale(
identifier: id,
locale: locale,
connectionId: null,
cancellationToken: cancellationToken
);
}
#endregion
//
#region New ...
//
// Titles ...
var newTitles = resource.Titles.Locales.Where(
l => !result.Titles.Locales.Any(r => r.Language.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
);
foreach (var locale in newTitles)
{
//
await titleResourceProvider.AddOrUpdateLocale(
identifier: id,
locale: locale,
connectionId: null,
cancellationToken: cancellationToken
);
}
//
// Descriptions ...
var newDescriptions = resource.Descriptions.Locales.Where(
l => !result.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
);
foreach (var locale in newDescriptions)
{
//
await descriptionResourceProvider.AddOrUpdateLocale(
identifier: id,
locale: locale,
connectionId: null,
cancellationToken: cancellationToken
);
}
#endregion
}
}
//
// Validate Action ...
isValid = id.IsValidIntId();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Get Result ...
result =
isDelete
? resource
: await GetResource(
id: id,
cancellationToken: cancellationToken
);
isValid = !result.IsNullOrDefault();
//
// Send Notification ...
if (isValid)
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: isNew
? XBaseEntityHubAction.Add.GetStringValue()
: isDelete
? XBaseEntityHubAction.Delete.GetStringValue()
: XBaseEntityHubAction.Update.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Get All Resources as Async Enumerable ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async IAsyncEnumerable<XSubCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
[EnumeratorCancellation] CancellationToken cancellationToken = default
)
{
//
var enumerable = provider.GetAllAsAsyncEnumerable(
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
orderBuilder: x => x.OrderBy(y => y.Id)
);
//
await foreach (var dto in enumerable)
{
//
if (cancellationToken.IsCancellationRequested)
{
yield break;
}
//
var resource = await GetResource(
id: dto.Id,
cancellationToken: cancellationToken
);
yield return resource;
}
}
/// <summary>
/// Get All Resources ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XSubCategoryResourceDto>> GetAllResources(
CancellationToken cancellationToken = default
)
{
//
var result = new List<XSubCategoryResourceDto>();
//
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
await foreach (var item in enumerable)
{
//
if (cancellationToken.IsCancellationRequested)
{
break;
}
//
result.Add(item);
}
//
return result;
}
/// <summary>
/// Find One Resource ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XSubCategoryResourceDto> FindOneResource(
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
CancellationToken cancellationToken = default
)
{
//
var isApproved = false;
XSubCategoryResourceDto result = null;
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
await foreach (var item in enumerable)
{
//
// Check Cancellation Token ...
if (cancellationToken.IsCancellationRequested)
{
break;
}
//
// Detect Predicate Condition ...
isApproved = predicate.Compile()(item);
if (isApproved)
{
//
result = item;
break;
}
}
//
return result;
}
/// <summary>
/// Find Many Resource ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XSubCategoryResourceDto>> FindManyResource(
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var isApproved = false;
var result = new List<XSubCategoryResourceDto>();
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
await foreach (var item in enumerable)
{
//
// Check Cancellation Token ...
if (cancellationToken.IsCancellationRequested)
{
break;
}
//
// Detect Predicate Condition ...
isApproved = predicate.Compile()(item);
if (isApproved)
{
result.Add(item);
}
}
//
// Apply Order ...
if (!orderBuilder.IsNull())
{
//
result =
orderBuilder(result.AsQueryable())
.ToList();
}
//
return result;
}
/// <summary>
/// Retrieve Resources by Query Pattern ...
/// </summary>
/// <param name="query"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<XSubCategoryResourceDto>> QueryResources(
XQuery query = null,
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Normalize Query ...
query = query.NormalizeQuery(dataServiceConfiguration);
//
var items = await FindManyResource(
predicate: predicate,
orderBuilder: orderBuilder,
cancellationToken: cancellationToken
);
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<XSubCategoryResourceDto>
{
Page = query.Page,
Items = [.. items],
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
#endregion
}
}