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>? Or(this ISpecification spec, ISpecification 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>(orExpression, parameter); return lambdaExpr; } public static Expression? CombineWhereExpressions(IEnumerable> 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; } }