persistence/DD.Persistence.Database/Extensions/SpecificationExtensions.cs

39 lines
1.4 KiB
C#

using Ardalis.Specification;
using DD.Persistence.Database.Helpers;
using System.Linq.Expressions;
namespace DD.Persistence.Database.Postgres.Extensions;
public static class SpecificationExtensions
{
public static Expression<Func<T, bool>>? Or<T>(this ISpecification<T> spec, ISpecification<T> otherSpec)
{
var parameter = Expression.Parameter(typeof(T), "x");
var exprSpec1 = CombineWhereExpressions(spec.WhereExpressions, parameter);
var exprSpec2 = CombineWhereExpressions(otherSpec.WhereExpressions, parameter);
Expression? orExpression = exprSpec1 is not null && exprSpec2 is not null
? Expression.OrElse(exprSpec1, exprSpec2)
: exprSpec1 ?? exprSpec2;
if (orExpression is null)
return null;
var lambdaExpr = Expression.Lambda<Func<T, bool>>(orExpression, parameter);
return lambdaExpr;
}
public static Expression? CombineWhereExpressions<T>(IEnumerable<WhereExpressionInfo<T>> whereExpressions, ParameterExpression parameter)
{
Expression? newExpr = null;
foreach (var where in whereExpressions)
{
var expr = ParameterReplacerVisitor.Replace(where.Filter.Body, where.Filter.Parameters[0], parameter);
newExpr = newExpr is null ? expr : Expression.AndAlso(newExpr, expr);
}
return newExpr;
}
}