1618 lines
53 KiB
C#
1618 lines
53 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 xExceptions.Constants;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xDataService.Extensions;
|
|
using xPushService.Constants;
|
|
using xPushService.Providers;
|
|
using xDataService.Configuration;
|
|
using xDataService.Models;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XCategoryProvider : XBaseProvided<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXCategoryProvider
|
|
{
|
|
private readonly IXCategoryServiceProvider provider;
|
|
private readonly XAppConfiguration appConfiguration;
|
|
private readonly XDataServiceConfiguration dataServiceConfiguration;
|
|
private readonly IXCategoryTitleResourceProvider titleResourceProvider;
|
|
private readonly IXCategoryDescriptionResourceProvider descriptionResourceProvider;
|
|
private readonly IXCategorySubCategoryReferenceProvider categorySubCategoryReferenceProvider;
|
|
|
|
public string Provider => categorySubCategoryReferenceProvider.Provider;
|
|
|
|
public XCategoryProvider(
|
|
XAppConfiguration appConfiguration,
|
|
IXCategoryServiceProvider provider,
|
|
XDataServiceConfiguration dataServiceConfiguration,
|
|
IXCategoryTitleResourceProvider titleResourceProvider,
|
|
IXCategoryDescriptionResourceProvider descriptionResourceProvider,
|
|
IXCategorySubCategoryReferenceProvider categorySubCategoryReferenceProvider
|
|
) : base(
|
|
provider,
|
|
permittedRoles: new string[] { }
|
|
)
|
|
{
|
|
//
|
|
this.provider = provider;
|
|
this.appConfiguration = appConfiguration;
|
|
this.titleResourceProvider = titleResourceProvider;
|
|
this.dataServiceConfiguration = dataServiceConfiguration;
|
|
this.descriptionResourceProvider = descriptionResourceProvider;
|
|
this.categorySubCategoryReferenceProvider = categorySubCategoryReferenceProvider;
|
|
}
|
|
|
|
//
|
|
#region Overrides ...
|
|
public override bool IsOwned(
|
|
XCategoryDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XCategory 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<XCategoryResourceDto> 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
|
|
);
|
|
|
|
//
|
|
var result = new XCategoryResourceDto
|
|
{
|
|
Item = item,
|
|
Titles = titleResource,
|
|
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<XCategoryResourceDto> Add(
|
|
XCategoryDto 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 Category by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> AddResource(
|
|
XCategoryResourceDto 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(il =>
|
|
il.Language.IsNullOrEmpty() ||
|
|
il.Value.IsNullOrEmpty());
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (item.Item.IsNullOrDefault())
|
|
{
|
|
item.Item = new XCategoryDto();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
try
|
|
{
|
|
//
|
|
// Add Category 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();
|
|
}
|
|
|
|
//
|
|
// 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<XCategoryResourceDto> 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<XCategoryResourceDto> Update(
|
|
int id,
|
|
XCategoryDto 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<XCategoryResourceDto> Refresh(
|
|
XCategoryResourceDto 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;
|
|
XCategoryResourceDto result = null;
|
|
|
|
//
|
|
// Check Item Exists ...
|
|
XCategoryDto 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 XCategoryDto
|
|
{
|
|
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<XCategoryResourceDto> 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<XCategoryResourceDto>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XCategoryResourceDto>();
|
|
|
|
//
|
|
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<XCategoryResourceDto> FindOneResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isApproved = false;
|
|
XCategoryResourceDto 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<XCategoryResourceDto>> FindManyResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isApproved = false;
|
|
var result = new List<XCategoryResourceDto>();
|
|
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<XCategoryResourceDto>> QueryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> 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<XCategoryResourceDto>
|
|
{
|
|
Page = query.Page,
|
|
Items = [.. items],
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory References ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryDto> GetReference(
|
|
int providedForId,
|
|
int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.GetReference(
|
|
forIndex: forIndex,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XCategoryDto>> GetAllReferences(
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.GetAllReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract all Referencing Models for Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XReference<int>>> GetAllReferencings(
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.GetAllReferencings(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count References ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountReferences(
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.CountReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XCategoryDto>> QueryReferences(
|
|
XQuery query,
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.QueryReferences(
|
|
query: query,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XCategoryDto model,
|
|
int providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.AddReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XCategoryDto model,
|
|
XReference<int> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.AddReference(
|
|
model: model,
|
|
reference: reference,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XCategoryDto model,
|
|
int providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.RemoveReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XCategoryDto model,
|
|
XReference<int> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.RemoveReference(
|
|
model: model,
|
|
reference: reference,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReferences(
|
|
int providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.RemoveReferences(
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
} |