diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 7015fadba..0fdf3de1b 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -9,8 +9,8 @@
true
-
-
+
+
diff --git a/src/api/framework/Core/Specifications/EntitiesByBaseFilterSpec.cs b/src/api/framework/Core/Specifications/EntitiesByBaseFilterSpec.cs
index 643bcb675..4b14bd2bf 100644
--- a/src/api/framework/Core/Specifications/EntitiesByBaseFilterSpec.cs
+++ b/src/api/framework/Core/Specifications/EntitiesByBaseFilterSpec.cs
@@ -3,13 +3,13 @@
namespace FSH.Framework.Core.Specifications;
-public class EntitiesByBaseFilterSpec : Specification
+public class EntitiesByBaseFilterSpec : Specification where T : class
{
public EntitiesByBaseFilterSpec(BaseFilter filter) =>
Query.SearchBy(filter);
}
-public class EntitiesByBaseFilterSpec : Specification
+public class EntitiesByBaseFilterSpec : Specification where T : class
{
public EntitiesByBaseFilterSpec(BaseFilter filter) =>
Query.SearchBy(filter);
diff --git a/src/api/framework/Core/Specifications/EntitiesByPaginationFilterSpec.cs b/src/api/framework/Core/Specifications/EntitiesByPaginationFilterSpec.cs
index abdf49eeb..a2ff6ba52 100644
--- a/src/api/framework/Core/Specifications/EntitiesByPaginationFilterSpec.cs
+++ b/src/api/framework/Core/Specifications/EntitiesByPaginationFilterSpec.cs
@@ -2,14 +2,14 @@
namespace FSH.Framework.Core.Specifications;
-public class EntitiesByPaginationFilterSpec : EntitiesByBaseFilterSpec
+public class EntitiesByPaginationFilterSpec : EntitiesByBaseFilterSpec where T : class
{
public EntitiesByPaginationFilterSpec(PaginationFilter filter)
: base(filter) =>
Query.PaginateBy(filter);
}
-public class EntitiesByPaginationFilterSpec : EntitiesByBaseFilterSpec
+public class EntitiesByPaginationFilterSpec : EntitiesByBaseFilterSpec where T : class
{
public EntitiesByPaginationFilterSpec(PaginationFilter filter)
: base(filter) =>
diff --git a/src/api/framework/Core/Specifications/SpecificationBuilderExtensions.cs b/src/api/framework/Core/Specifications/SpecificationBuilderExtensions.cs
index 81b352056..177449419 100644
--- a/src/api/framework/Core/Specifications/SpecificationBuilderExtensions.cs
+++ b/src/api/framework/Core/Specifications/SpecificationBuilderExtensions.cs
@@ -7,10 +7,9 @@
namespace FSH.Framework.Core.Specifications;
-// See https://github.com/ardalis/Specification/issues/53
public static class SpecificationBuilderExtensions
{
- public static ISpecificationBuilder SearchBy(this ISpecificationBuilder query, BaseFilter filter) =>
+ public static ISpecificationBuilder SearchBy(this ISpecificationBuilder query, BaseFilter filter) where T : class =>
query
.SearchByKeyword(filter.Keyword)
.AdvancedSearch(filter.AdvancedSearch)
@@ -38,20 +37,20 @@ public static ISpecificationBuilder PaginateBy(this ISpecificationBuilder<
.OrderBy(filter.OrderBy);
}
- public static IOrderedSpecificationBuilder SearchByKeyword(
+ public static ISpecificationBuilder SearchByKeyword(
this ISpecificationBuilder specificationBuilder,
- string? keyword) =>
+ string? keyword) where T : class =>
specificationBuilder.AdvancedSearch(new Search { Keyword = keyword });
- public static IOrderedSpecificationBuilder AdvancedSearch(
+ public static ISpecificationBuilder AdvancedSearch(
this ISpecificationBuilder specificationBuilder,
- Search? search)
+ Search? search) where T : class
{
if (!string.IsNullOrEmpty(search?.Keyword))
{
if (search.Fields?.Any() is true)
{
- // search seleted fields (can contain deeper nested fields)
+ // search selected fields (can contain deeper nested fields)
foreach (string field in search.Fields)
{
var paramExpr = Expression.Parameter(typeof(T));
@@ -76,7 +75,7 @@ public static IOrderedSpecificationBuilder AdvancedSearch(
}
}
- return new OrderedSpecificationBuilder(specificationBuilder.Specification);
+ return specificationBuilder;
}
private static void AddSearchPropertyByKeyword(
@@ -84,7 +83,7 @@ private static void AddSearchPropertyByKeyword(
Expression propertyExpr,
ParameterExpression paramExpr,
string keyword,
- string operatorSearch = FilterOperator.CONTAINS)
+ string operatorSearch = FilterOperator.CONTAINS) where T : class
{
if (propertyExpr is not MemberExpression memberExpr || memberExpr.Member is not PropertyInfo property)
{
@@ -112,13 +111,12 @@ private static void AddSearchPropertyByKeyword(
var toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes);
Expression callToLowerMethod = Expression.Call(selectorExpr, toLowerMethod!);
- var selector = Expression.Lambda>(callToLowerMethod, paramExpr);
+ var selector = Expression.Lambda>(callToLowerMethod, paramExpr);
- ((List>)specificationBuilder.Specification.SearchCriterias)
- .Add(new SearchExpressionInfo(selector, searchTerm, 1));
+ specificationBuilder.Search(selector, searchTerm, 1);
}
- public static IOrderedSpecificationBuilder AdvancedFilter(
+ public static ISpecificationBuilder AdvancedFilter(
this ISpecificationBuilder specificationBuilder,
Filter? filter)
{
@@ -126,24 +124,24 @@ public static IOrderedSpecificationBuilder AdvancedFilter(
{
var parameter = Expression.Parameter(typeof(T));
- Expression binaryExpresioFilter;
+ Expression binaryExpressionFilter;
if (!string.IsNullOrEmpty(filter.Logic))
{
if (filter.Filters is null) throw new CustomException("The Filters attribute is required when declaring a logic");
- binaryExpresioFilter = CreateFilterExpression(filter.Logic, filter.Filters, parameter);
+ binaryExpressionFilter = CreateFilterExpression(filter.Logic, filter.Filters, parameter);
}
else
{
var filterValid = GetValidFilter(filter);
- binaryExpresioFilter = CreateFilterExpression(filterValid.Field!, filterValid.Operator!, filterValid.Value, parameter);
+ binaryExpressionFilter = CreateFilterExpression(filterValid.Field!, filterValid.Operator!, filterValid.Value, parameter);
}
- ((List>)specificationBuilder.Specification.WhereExpressions)
- .Add(new WhereExpressionInfo(Expression.Lambda>(binaryExpresioFilter, parameter)));
+ var expr = Expression.Lambda>(binaryExpressionFilter, parameter);
+ specificationBuilder.Where(expr);
}
- return new OrderedSpecificationBuilder(specificationBuilder.Specification);
+ return specificationBuilder;
}
private static Expression CreateFilterExpression(
@@ -155,20 +153,20 @@ private static Expression CreateFilterExpression(
foreach (var filter in filters)
{
- Expression bExpresionFilter;
+ Expression bExpressionFilter;
if (!string.IsNullOrEmpty(filter.Logic))
{
if (filter.Filters is null) throw new CustomException("The Filters attribute is required when declaring a logic");
- bExpresionFilter = CreateFilterExpression(filter.Logic, filter.Filters, parameter);
+ bExpressionFilter = CreateFilterExpression(filter.Logic, filter.Filters, parameter);
}
else
{
var filterValid = GetValidFilter(filter);
- bExpresionFilter = CreateFilterExpression(filterValid.Field!, filterValid.Operator!, filterValid.Value, parameter);
+ bExpressionFilter = CreateFilterExpression(filterValid.Field!, filterValid.Operator!, filterValid.Value, parameter);
}
- filterExpression = filterExpression is null ? bExpresionFilter : CombineFilter(logic, filterExpression, bExpresionFilter);
+ filterExpression = filterExpression is null ? bExpressionFilter : CombineFilter(logic, filterExpression, bExpressionFilter);
}
return filterExpression;
@@ -180,9 +178,9 @@ private static Expression CreateFilterExpression(
object? value,
ParameterExpression parameter)
{
- var propertyExpresion = GetPropertyExpression(field, parameter);
- var valueExpresion = GeValuetExpression(field, value, propertyExpresion.Type);
- return CreateFilterExpression(propertyExpresion, valueExpresion, filterOperator);
+ var propertyExpression = GetPropertyExpression(field, parameter);
+ var valueExpression = GeValueExpression(field, value, propertyExpression.Type);
+ return CreateFilterExpression(propertyExpression, valueExpression, filterOperator);
}
private static Expression CreateFilterExpression(
@@ -211,14 +209,14 @@ private static Expression CreateFilterExpression(
};
}
- private static Expression CombineFilter(
+ private static BinaryExpression CombineFilter(
string filterOperator,
- Expression bExpresionBase,
- Expression bExpresion) => filterOperator switch
+ Expression bExpressionBase,
+ Expression bExpression) => filterOperator switch
{
- FilterLogic.AND => Expression.And(bExpresionBase, bExpresion),
- FilterLogic.OR => Expression.Or(bExpresionBase, bExpresion),
- FilterLogic.XOR => Expression.ExclusiveOr(bExpresionBase, bExpresion),
+ FilterLogic.AND => Expression.And(bExpressionBase, bExpression),
+ FilterLogic.OR => Expression.Or(bExpressionBase, bExpression),
+ FilterLogic.XOR => Expression.ExclusiveOr(bExpressionBase, bExpression),
_ => throw new ArgumentException("FilterLogic is not valid."),
};
@@ -238,7 +236,7 @@ private static MemberExpression GetPropertyExpression(
private static string GetStringFromJsonElement(object value)
=> ((JsonElement)value).GetString()!;
- private static ConstantExpression GeValuetExpression(
+ private static ConstantExpression GeValueExpression(
string field,
object? value,
Type propertyType)
@@ -303,10 +301,12 @@ private static Filter GetValidFilter(Filter filter)
return filter;
}
- public static IOrderedSpecificationBuilder OrderBy(
+ public static ISpecificationBuilder OrderBy(
this ISpecificationBuilder specificationBuilder,
string[]? orderByFields)
{
+ IOrderedSpecificationBuilder orderedBuilder = null!;
+
if (orderByFields is not null)
{
foreach (var field in ParseOrderBy(orderByFields))
@@ -323,12 +323,18 @@ public static IOrderedSpecificationBuilder OrderBy(
Expression.Convert(propertyExpr, typeof(object)),
paramExpr);
- ((List>)specificationBuilder.Specification.OrderExpressions)
- .Add(new OrderExpressionInfo(keySelector, field.Value));
+ orderedBuilder = field.Value switch
+ {
+ OrderTypeEnum.OrderBy => specificationBuilder.OrderBy(keySelector),
+ OrderTypeEnum.OrderByDescending => specificationBuilder.OrderByDescending(keySelector),
+ OrderTypeEnum.ThenBy => orderedBuilder.ThenBy(keySelector),
+ OrderTypeEnum.ThenByDescending => orderedBuilder.ThenByDescending(keySelector),
+ _ => throw new CustomException("OrderTypeEnum is not valid."),
+ };
}
}
- return new OrderedSpecificationBuilder(specificationBuilder.Specification);
+ return specificationBuilder;
}
private static Dictionary ParseOrderBy(string[] orderByFields) =>