Last works on Tag Service ...

This commit is contained in:
2025-12-07 20:53:22 +03:30
parent 8958ad5682
commit bfe1150139
6 changed files with 1938 additions and 1 deletions
+84
View File
@@ -0,0 +1,84 @@
using System.Collections.Generic;
using System.Linq;
using xCommons.Extensions;
using xTagService.Models.Dtos;
using xTagService.Models.Entities;
namespace xTagService.Extensions
{
public static class xTagServiceExtension
{
/// <summary>
/// Map Global Properties From XFile to XFile Dto ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XTagDto ToDto(this XTag source)
{
//
XTagDto result = null;
//
if (!source.IsNullOrDefault())
{
//
result = new XTagDto();
result = result.UpdateData(
updateWith: source,
propertyBlackList: new List<string>
{
nameof(XTag.Deleted),
nameof(XTag.References),
}
);
//
// Preparing List ...
if (!source.References.IsNullOrEmpty())
{
//
result.References = source.References
.ParseListString<string>()
.ToList();
}
}
//
return result;
}
/// <summary>
/// Converts a Dto to Entity Representation ...
/// Ignore ID Property ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XTag FromDto(this XTagDto source)
{
//
var result = new XTag();
//
if (!source.IsNull())
{
//
result = result.UpdateData(
updateWith: source,
propertyBlackList: new List<string>
{
nameof(XTag.Deleted),
nameof(XTag.References),
}
);
//
if (!source.References.IsNull() && source.References.HasChild()) {
result.References = source.References.ToListString();
}
}
//
return result;
}
}
}
+237
View File
@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using xModels.Dtos;
using xTagService.Models.Dtos;
using xTagService.Models.Entities;
namespace xTagService.Interfaces
{
public interface IXBaseTagProvider<TKey>
{
//
#region Props ...
/// <summary>
/// Specified Provider ...
/// </summary>
string ProvideFor { get; }
/// <summary>
/// Specified Provider Repositroy ...
/// </summary>
IXTagProvider Provider { get; }
#endregion
//
#region Helper ...
/// <summary>
/// Get Specified Identifier ...
/// </summary>
/// <param name="forProvidedId"></param>
/// <returns></returns>
string GetIdentifier(TKey forProvidedId);
#endregion
//
#region Implementation ...
/// <summary>
/// Attach Specified Label to Specified Provided Model ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XTagDto> Attach(
string tag,
TKey forProvidedId
);
/// <summary>
/// Detach Specified Label From Specified Provided Model ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XTagDto> Detach(
string tag,
TKey forProvidedId
);
/// <summary>
/// Add Specified Tag ...
/// </summary>
/// <param name="model"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XTagDto> Add(
XTagDto model,
TKey forProvidedId
);
/// <summary>
/// Retrieve Specified Item as Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<XTagDto> Get(int id);
/// <summary>
/// Retrieve Specified Tag by it's Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
Task<XTagDto> GetTag(string tag);
/// <summary>
/// Retrieve Specified Tag by it's Label ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XTagDto> GetTagFor(
string tag,
TKey forProvidedId
);
/// <summary>
/// Retrieve All Items as Dto ...
/// </summary>
/// <returns></returns>
Task<IEnumerable<XTagDto>> GetAll();
/// <summary>
/// Retrieve All Items as Dto ...
/// </summary>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<IEnumerable<XTagDto>> GetTags(TKey forProvidedId);
/// <summary>
/// Find Specified Item by Condition ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
Task<XTagDto> FindOne(Expression<Func<XTag, bool>> whereClause);
/// <summary>
/// Find Many Items based on Conditions ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
Task<IEnumerable<XTagDto>> FindMany(Expression<Func<XTag, bool>> whereClause);
/// <summary>
/// Find Many Items based on Conditions ...
/// </summary>
/// <param name="whereClause"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<IEnumerable<XTagDto>> FindManyFor(
Expression<Func<XTag, bool>> whereClause,
TKey forProvidedId
);
/// <summary>
/// Query Model retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
Task<XQueryResult<XTagDto>> Query(XQuery query);
/// <summary>
/// Query Model retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XQueryResult<XTagDto>> QueryTagsFor(
XQuery query,
TKey forProvidedId
);
/// <summary>
/// Query Conditional Retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="whereClause"></param>
/// <returns></returns>
Task<XQueryResult<XTagDto>> ConditionalQuery(
XQuery query,
Expression<Func<XTag, bool>> whereClause
);
/// <summary>
/// Query Conditional Retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="whereClause"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XQueryResult<XTagDto>> ConditionalQueryTagsFor(
XQuery query,
Expression<Func<XTag, bool>> whereClause,
TKey forProvidedId
);
/// <summary>
/// Remove Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<XTagDto> Remove(
int id
);
/// <summary>
/// Update Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <param name="model"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<XTagDto> Update(
int id,
XTagDto model,
TKey forProvidedId
);
/// <summary>
/// Count Exists Entities ...
/// </summary>
/// <returns></returns>
Task<int> Count();
/// <summary>
/// Check Entity Exists or not ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<bool> IsExists(int id);
/// <summary>
/// Check Tag Exists by Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
Task<bool> IsTagExists(string tag);
/// <summary>
/// Check Tag Exists by Label ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<bool> IsTagExistsFor(
string tag,
TKey forProvidedId
);
/// <summary>
/// Check Specified Model has Tag or not ...
/// </summary>
/// <param name="forProvidedId"></param>
/// <returns></returns>
Task<bool> IsExistsFor(TKey forProvidedId);
#endregion
}
}
+153
View File
@@ -0,0 +1,153 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using xDataService.Configuration;
using xIdentityModels.Models;
using xIdentityService.Interfaces;
using xModels.Dtos;
using xTagService.Hubs;
using xTagService.Interfaces.Entities;
using xTagService.Models.Dtos;
using xTagService.Models.Entities;
namespace xTagService.Interfaces
{
public interface IXTagProvider
{
//
#region Props ...
IXTagRepository Repository { get; }
IHubContext<XTagEntityHub> Hub { get; }
IXIdentityProvider IdentityProvider { get; }
XDataServiceConfiguration DataConfiguration { get; }
#endregion
//
#region Helpers ...
/// <summary>
/// Converts an Entity to Dto ...
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
XTagDto ToXTagDto(XTag model);
/// <summary>
/// Converts a List of Entitiies to List of Dto's ...
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
IEnumerable<XTagDto> ToXTagDtoList(IEnumerable<XTag> models);
/// <summary>
/// Converts Query Result of Entities to Dto ...
/// </summary>
/// <param name="queryResult"></param>
/// <returns></returns>
XQueryResult<XTagDto> ToXTagDtoQueryResult(XQueryResult<XTag> queryResult);
#endregion
//
#region Tools ...
/// <summary>
/// Add Specified Tag ...
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<XTagDto> Add(XTagDto model);
/// <summary>
/// Retrieve Specified Item as Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<XTagDto> Get(int id);
/// <summary>
/// Retrieve Specified Tag by it's Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
Task<XTagDto> GetTag(string tag);
/// <summary>
/// Retrieve All Items as Dto ...
/// </summary>
/// <returns></returns>
Task<IEnumerable<XTagDto>> GetAll();
/// <summary>
/// Find Specified Item by Condition ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
Task<XTagDto> FindOne(Expression<Func<XTag, bool>> whereClause);
/// <summary>
/// Find Many Items based on Conditions ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
Task<IEnumerable<XTagDto>> FindMany(Expression<Func<XTag, bool>> whereClause);
/// <summary>
/// Query Model retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
Task<XQueryResult<XTagDto>> Query(XQuery query);
/// <summary>
/// Query Conditional Retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="whereClause"></param>
/// <returns></returns>
Task<XQueryResult<XTagDto>> ConditionalQuery(
XQuery query,
Expression<Func<XTag, bool>> whereClause
);
/// <summary>
/// Remove Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<XTagDto> Remove(
int id
);
/// <summary>
/// Update Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <param name="model"></param>
/// <returns></returns>
Task<XTagDto> Update(
int id,
XTagDto model
);
/// <summary>
/// Count Exists Entities ...
/// </summary>
/// <returns></returns>
Task<int> Count();
/// <summary>
/// Check Entity Exists or not ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<bool> IsExists(int id);
/// <summary>
/// Check Tag Exists by Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
Task<bool> IsTagExists(string tag);
#endregion
}
}
+1 -1
View File
@@ -7,6 +7,6 @@ namespace xTagService.Models.Dtos
{
public int Id { get; set; }
public string Tag { get; set; }
public IList<string> Reference = new List<string>();
public IList<string> References = new List<string>();
}
}
+987
View File
@@ -0,0 +1,987 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using xCommons.Extensions;
using xDataService.Extensions;
using xExceptions.Constants;
using xModels.Dtos;
using xTagService.Interfaces;
using xTagService.Models.Dtos;
using xTagService.Models.Entities;
namespace xTagService.Providers
{
public abstract class XBaseTagProvider<TKey> : IXBaseTagProvider<TKey>
{
//
#region Props ...
/// <summary>
/// Specified Provider ...
/// </summary>
public string ProvideFor { get; }
/// <summary>
/// Specified Provider Repositroy ...
/// </summary>
public IXTagProvider Provider { get; }
#endregion
//
#region Constructor ...
public XBaseTagProvider(
string providedFor,
IXTagProvider tagProvider
)
{
//
Provider = tagProvider;
ProvideFor = providedFor;
}
#endregion
//
#region Helper ...
/// <summary>
/// Get Specified Identifier ...
/// </summary>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public string GetIdentifier(TKey forProvidedId)
{
//
var result = string.Empty;
//
result = $"{ProvideFor}_{forProvidedId}";
//
return result;
}
#endregion
//
#region Implementation ...
/// <summary>
/// Attach Specified Label to Specified Provided Model ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XTagDto> Attach(
string tag,
TKey forProvidedId
)
{
//
// Validate ...
var isValid = !tag.IsNullOrEmpty() &&
!forProvidedId.IsNull();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Generate Identifier ...
var identifier = GetIdentifier(forProvidedId);
//
// Check Tag Exists or not ...
isValid = await Provider.IsTagExists(tag);
//
XTagDto result = null;
//
// Add new XTag Entity ...
if (!isValid)
{
//
result = await Provider.Add(new XTagDto
{
Tag = tag,
References = new List<string> { identifier }
});
}
//
// Update Exists Tag Enttiy ...
else
{
//
result = await Provider.GetTag(tag);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
result.References.Add(identifier);
result = await Provider.Update(result.Id, result);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
}
//
return result;
}
/// <summary>
/// Detach Specified Label From Specified Provided Model ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XTagDto> Detach(
string tag,
TKey forProvidedId
)
{
//
// Validate ...
var isValid = !tag.IsNullOrEmpty() &&
!forProvidedId.IsNull();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Generate Identifier ...
var identifier = GetIdentifier(forProvidedId);
//
XTagDto result = null;
//
// Check Tag Exists or not ...
isValid = await IsTagExistsFor(
tag: tag,
forProvidedId: forProvidedId
);
if (!isValid)
{
return result;
}
//
// Remove id From XTag References ...
result = await GetTagFor(
tag: tag,
forProvidedId: forProvidedId
);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Remove identifier ...
result.References = result
.References
.Where(rf => rf.ToNormalString() != identifier.ToNormalString())
.ToList();
result = await Provider.Update(result.Id, result);
//
return result;
}
/// <summary>
/// Add Specified Tag ...
/// </summary>
/// <param name="model"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XTagDto> Add(
XTagDto model,
TKey forProvidedId
)
{
//
// Validate ...
var isValid = !model.IsNull() &&
!forProvidedId.IsNull();
if (!isValid)
{
return null;
}
//
// Refrences ...
var identifier = GetIdentifier(forProvidedId);
if (!model.References.IsNull() && model.References.HasChild())
{
//
isValid = !identifier.IsNullOrEmpty() &&
!model.References.Any(r => r.ToNormalString() == identifier.ToNormalString());
}
if (isValid)
{
model.References.Add(identifier);
}
//
model = await Provider.Add(model);
//
return model;
}
/// <summary>
/// Retrieve Specified Item as Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<XTagDto> Get(int id)
{
//
XTagDto result = null;
//
var isValid = await Provider.IsExists(id);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var dto = await Provider.Get(id);
isValid = !dto.IsNullOrDefault();
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Validate Dto ...
isValid = dto.References.Any(e => e.ToNormalString()
.Contains(ProvideFor.ToNormalString()));
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
result = dto;
//
return result;
}
/// <summary>
/// Retrieve Specified Tag by it's Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public async Task<XTagDto> GetTag(string tag)
{
//
var isValid = !tag.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
var dto = await Provider.GetTag(tag);
isValid = !dto.IsNullOrDefault();
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Check Identifier ...
isValid = !dto.References.IsNull() &&
!dto.References.HasChild() &&
dto.References.Any(e => e.ToNormalString().Contains(ProvideFor.ToNormalString()));
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
return dto;
}
/// <summary>
/// Retrieve Specified Tag by it's Label ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XTagDto> GetTagFor(
string tag,
TKey forProvidedId
)
{
//
XTagDto result = null;
//
var dtos = await GetTags(forProvidedId);
if (!dtos.IsNull() && dtos.HasChild())
{
//
result = dtos.Where(dto => dto.Tag.ToNormalString() == tag.ToNormalString())
.FirstOrDefault();
}
//
return result;
}
/// <summary>
/// Retrieve All Items as Dto ...
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<XTagDto>> GetAll()
{
//
var result = await Provider.GetAll();
if (!result.IsNull() && result.HasChild())
{
result = result
.Where(e => e.References.Any(er => er.ToNormalString().Contains(ProvideFor.ToNormalString())));
}
//
return result;
}
/// <summary>
/// Retrieve All Items as Dto ...
/// </summary>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<IEnumerable<XTagDto>> GetTags(TKey forProvidedId)
{
//
var result = new List<XTagDto>();
//
string identifier = GetIdentifier(forProvidedId);
var tags = await GetAll();
if (!tags.IsNull() && tags.HasChild())
{
//
result =
tags.Where(t => t.References.Any(tr => tr.ToNormalString() == identifier.ToNormalString()))
.ToList();
}
//
return result;
}
/// <summary>
/// Find Specified Item by Condition ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
public async Task<XTagDto> FindOne(Expression<Func<XTag, bool>> whereClause)
{
//
var dto = await Provider.FindOne(whereClause);
if (dto.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
var isValid = dto.References.Any(dr => dr.ToNormalString().Contains(ProvideFor.ToNormalString()));
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
return dto;
}
/// <summary>
/// Find Many Items based on Conditions ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
public async Task<IEnumerable<XTagDto>> FindMany(Expression<Func<XTag, bool>> whereClause)
{
//
var result = new List<XTagDto>();
var dtos = await Provider.FindMany(whereClause);
if (!dtos.IsNull() && dtos.HasChild())
{
//
bool isValid = false;
dtos.ToList()
.ForEach(dto =>
{
//
isValid = dto.References.HasChild() &&
dto.References.Any(r => r.ToNormalString().Contains(ProvideFor.ToNormalString()));
if (isValid)
{
result.Add(dto);
}
});
}
//
return result;
}
/// <summary>
/// Find Many Items based on Conditions ...
/// </summary>
/// <param name="whereClause"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<IEnumerable<XTagDto>> FindManyFor(
Expression<Func<XTag, bool>> whereClause,
TKey forProvidedId
)
{
//
var result = new List<XTagDto>();
var dtos = await Provider.FindMany(whereClause);
if (!dtos.IsNull() && dtos.HasChild())
{
//
bool isValid = false;
var identifier = GetIdentifier(forProvidedId);
dtos.ToList()
.ForEach(dto =>
{
//
isValid = dto.References.HasChild() &&
dto.References.Any(r => r.ToNormalString() == identifier.ToNormalString());
if (isValid)
{
result.Add(dto);
}
});
}
//
return result;
}
/// <summary>
/// Query Model retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public async Task<XQueryResult<XTagDto>> Query(XQuery query)
{
//
// Validate ...
if (query.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(Provider.DataConfiguration);
//
var items = (await GetAll())
.ToList();
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter)
.ToList();
}
//
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
)
.ToList();
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
)
.ToList();
}
//
// Prepare Result ...
var result = new XQueryResult<XTagDto>
{
Page = query.Page,
Items = items.ToList(),
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Query Model retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XQueryResult<XTagDto>> QueryTagsFor(
XQuery query,
TKey forProvidedId
)
{
//
// Validate ...
if (query.IsNull() || forProvidedId.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(Provider.DataConfiguration);
//
var items = (await GetTags(forProvidedId))
.ToList();
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter)
.ToList();
}
//
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
)
.ToList();
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
)
.ToList();
}
//
// Prepare Result ...
var result = new XQueryResult<XTagDto>
{
Page = query.Page,
Items = items.ToList(),
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Query Conditional Retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="whereClause"></param>
/// <returns></returns>
public async Task<XQueryResult<XTagDto>> ConditionalQuery(
XQuery query,
Expression<Func<XTag, bool>> whereClause
)
{
//
// Validate ...
if (query.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(Provider.DataConfiguration);
//
var items = (await FindMany(whereClause))
.ToList();
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter)
.ToList();
}
//
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
)
.ToList();
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
)
.ToList();
}
//
// Prepare Result ...
var result = new XQueryResult<XTagDto>
{
Page = query.Page,
Items = items.ToList(),
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Query Conditional Retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="whereClause"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XQueryResult<XTagDto>> ConditionalQueryTagsFor(
XQuery query,
Expression<Func<XTag, bool>> whereClause,
TKey forProvidedId
)
{
//
// Validate ...
if (query.IsNull() || forProvidedId.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(Provider.DataConfiguration);
//
var items = (await FindManyFor(
whereClause: whereClause,
forProvidedId: forProvidedId
))
.ToList();
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter)
.ToList();
}
//
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
)
.ToList();
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
)
.ToList();
}
//
// Prepare Result ...
var result = new XQueryResult<XTagDto>
{
Page = query.Page,
Items = items.ToList(),
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Remove Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<XTagDto> Remove(
int id
)
{
//
var isValid = id.IsValidIntId();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
isValid = await IsExists(id);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var result = await Provider.Remove(id);
if (result.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
return result;
}
/// <summary>
/// Update Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <param name="model"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<XTagDto> Update(
int id,
XTagDto model,
TKey forProvidedId
)
{
//
// Validate ...
var identifier = GetIdentifier(forProvidedId);
bool isValid = id.IsValidIntId() &&
!forProvidedId.IsNull() &&
!model.IsNullOrDefault() &&
!model.References.IsNull() &&
!identifier.IsNullOrEmpty() &&
model.References.Any(er => er.ToNormalString() == identifier.ToNormalString());
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
var result = await Provider.Update(id, model);
if (result.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
return result;
}
/// <summary>
/// Count Exists Entities ...
/// </summary>
/// <returns></returns>
public async Task<int> Count()
{
return (await GetAll()).Count();
}
/// <summary>
/// Check Entity Exists or not ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<bool> IsExists(int id)
{
//
var result = (await GetAll()).Any(e => e.Id == id);
//
return result;
}
/// <summary>
/// Check Tag Exists by Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public async Task<bool> IsTagExists(string tag)
{
//
var result = !(await GetTag(tag))
.IsNullOrDefault();
//
return result;
}
/// <summary>
/// Check Specified Model has Tag or not ...
/// </summary>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<bool> IsExistsFor(TKey forProvidedId)
{
//
// Validate ...
var result = !forProvidedId.IsNull();
if (!result)
{
return result;
}
//
result = (await GetTags(forProvidedId)).Count() >= 1;
//
return result;
}
/// <summary>
/// Check Tag Exists by Label ...
/// </summary>
/// <param name="tag"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
public async Task<bool> IsTagExistsFor(
string tag,
TKey forProvidedId
)
{
//
var result = !(await GetTagFor(
tag: tag,
forProvidedId: forProvidedId
))
.IsNullOrDefault();
//
return result;
}
#endregion
}
}
+476
View File
@@ -0,0 +1,476 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using xCommons.Extensions;
using xDataService.Configuration;
using xExceptions.Constants;
using xIdentityService.Interfaces;
using xModels.Dtos;
using xTagService.Extensions;
using xTagService.Hubs;
using xTagService.Interfaces;
using xTagService.Interfaces.Entities;
using xTagService.Models.Dtos;
using xTagService.Models.Entities;
namespace xTagService.Providers
{
public class XTagProvider : IXTagProvider
{
//
#region Props ...
public IXTagRepository Repository { get; }
public IHubContext<XTagEntityHub> Hub { get; }
public IXIdentityProvider IdentityProvider { get; }
public XDataServiceConfiguration DataConfiguration { get; }
#endregion
//
#region Constructor ...
public XTagProvider(
IXTagRepository repository,
IXIdentityProvider identityProvider,
XDataServiceConfiguration dataConfiguration,
IHubContext<XTagEntityHub> hub = null
)
{
//
Hub = hub;
Repository = repository;
IdentityProvider = identityProvider;
DataConfiguration = dataConfiguration;
}
#endregion
//
#region Helpers ....
/// <summary>
/// Converts an Entity to Dto ...
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public XTagDto ToXTagDto(XTag model)
{
return model.ToDto();
}
/// <summary>
/// Converts a List of Entitiies to List of Dto's ...
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public IEnumerable<XTagDto> ToXTagDtoList(IEnumerable<XTag> models)
{
//
var result = new List<XTagDto>();
//
if (!models.IsNull() && models.HasChild())
{
//
foreach (var model in models)
{
//
var dto = ToXTagDto(model);
if (!dto.IsNullOrDefault())
{
result.Add(dto);
}
}
}
//
return result;
}
/// <summary>
/// Converts Query Result of Entities to Dto ...
/// </summary>
/// <param name="queryResult"></param>
/// <returns></returns>
public XQueryResult<XTagDto> ToXTagDtoQueryResult(XQueryResult<XTag> queryResult)
{
//
var result = new XQueryResult<XTagDto>();
//
if (!queryResult.IsNullOrDefault())
{
//
result.Page = queryResult.Page;
result.PageSize = queryResult.PageSize;
result.TotalItems = queryResult.TotalItems;
result.TotalPages = queryResult.TotalPages;
result.TotalFilteredItems = queryResult.TotalFilteredItems;
result.TotalFilteredPages = queryResult.TotalFilteredPages;
//
if (!queryResult.Items.IsNull() && queryResult.Items.HasChild())
{
result.Items = ToXTagDtoList(queryResult.Items);
}
}
//
return result;
}
#endregion
//
#region Tools ...
/// <summary>
/// Add Specified Tag ...
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<XTagDto> Add(XTagDto model)
{
//
XTagDto result = null;
//
if (!model.IsNullOrDefault())
{
//
// Converts to Entity ...
var entitiy = model.FromDto();
if (entitiy.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
entitiy = await Repository.AddAsync(entitiy);
if (entitiy.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
result = ToXTagDto(entitiy);
}
//
return result;
}
/// <summary>
/// Retrieve Specified Item as Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<XTagDto> Get(int id)
{
//
var result = new XTagDto();
if (!id.IsValidIntId())
{
XException.InvalidArgs.Throw();
}
//
if (id.IsValidIntId())
{
//
var entity = await Repository.GetAsync(id);
if (entity.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
result = ToXTagDto(entity);
if (result.IsNullOrDefault())
{
XException.NotFound.Throw();
}
}
//
return result;
}
/// <summary>
/// Retrieve Specified Tag by it's Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public async Task<XTagDto> GetTag(string tag)
{
//
// Validate ...
if (tag.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
var result = await FindOne(e => e.Tag.ToNormalString() == tag.ToNormalString());
if (result.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
return result;
}
/// <summary>
/// Retrieve All Items as Dto ...
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<XTagDto>> GetAll()
{
//
var result = new List<XTagDto>();
//
var entities = await Repository.GetAllAsync();
if (!entities.IsNull() && entities.HasChild())
{
//
result = ToXTagDtoList(entities)
.ToList();
}
//
return result;
}
/// <summary>
/// Find Specified Item by Condition ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
public async Task<XTagDto> FindOne(Expression<Func<XTag, bool>> whereClause)
{
//
XTagDto result = null;
//
var entitiy = await Repository.FindOneAsync(whereClause);
if (!entitiy.IsNullOrDefault())
{
result = ToXTagDto(entitiy);
}
//
return result;
}
/// <summary>
/// Find Many Items based on Conditions ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
public async Task<IEnumerable<XTagDto>> FindMany(Expression<Func<XTag, bool>> whereClause)
{
//
var result = new List<XTagDto>();
//
var entities = await Repository.FindManyAsync(whereClause);
if (!entities.IsNull() || entities.HasChild())
{
//
result = ToXTagDtoList(entities)
.ToList();
}
//
return result;
}
/// <summary>
/// Query Model retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public async Task<XQueryResult<XTagDto>> Query(XQuery query)
{
//
var result = new XQueryResult<XTagDto>();
//
var queryResult = await Repository.QueryAsync(query);
if (!queryResult.IsNull())
{
result = ToXTagDtoQueryResult(queryResult);
}
//
return result;
}
/// <summary>
/// Query Conditional Retrieving Dtos ...
/// </summary>
/// <param name="query"></param>
/// <param name="whereClause"></param>
/// <returns></returns>
public async Task<XQueryResult<XTagDto>> ConditionalQuery(
XQuery query,
Expression<Func<XTag, bool>> whereClause
)
{
//
var result = new XQueryResult<XTagDto>();
//
var queryResult = await Repository.ConditionalQueryAsync(
query: query,
whereClause: whereClause
);
if (!queryResult.IsNull())
{
result = ToXTagDtoQueryResult(queryResult);
}
//
return result;
}
/// <summary>
/// Remove Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<XTagDto> Remove(
int id
)
{
//
// Validate ...
var isValid = id.IsValidIntId();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Exists ...
isValid = await IsExists(id);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var entity = await Repository.RemoveAsync(id);
//
XTagDto result = null;
if (!entity.IsNullOrDefault())
{
result = ToXTagDto(entity);
}
//
return result;
}
/// <summary>
/// Update Specified Dto ...
/// </summary>
/// <param name="id"></param>
/// <param name="model"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
public async Task<XTagDto> Update(
int id,
XTagDto model
)
{
//
// Validate ...
var isValid = id.IsValidIntId();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
XTagDto result = null;
//
// Check Exists ...
isValid = await IsExists(id);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var entity = await Repository.GetAsync(id);
if (entity.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
var tagEntity = model.FromDto();
entity = entity.UpdateData(
updateWith: entity,
propertyBlackList: new List<string>
{
nameof(XTagDto.Id),
nameof(XTagDto.References)
}
);
entity.References = tagEntity.References;
entity = await Repository.UpdateAsync(id, entity);
if (!entity.IsNullOrDefault())
{
result = ToXTagDto(entity);
}
//
return result;
}
/// <summary>
/// Count Exists Entities ...
/// </summary>
/// <returns></returns>
public async Task<int> Count()
{
return await Repository.CountAsync();
}
/// <summary>
/// Check Entity Exists or not ...
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<bool> IsExists(int id)
{
return await Repository.IsExistsAsync(id);
}
/// <summary>
/// Check Tag Exists by Label ...
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public async Task<bool> IsTagExists(string tag)
{
//
var result = false;
//
if (!tag.IsNullOrEmpty())
{
//
var dto = await FindOne(e => e.Tag.ToNormalString() == tag.ToNormalString());
result = !dto.IsNullOrDefault();
}
//
return result;
}
#endregion
}
}