I have:
public class TotalPeriod
{
public ICollection<SubPeriod> SubPeriods { get; set; }
....
}
public class SubPeriod
{
public ICollection<SmallerSubPeriod> SmallerSubPeriods { get; set; }
....
}
public class SmallerSubPeriod
{
public Payment Payment { get; set; }
....
}
public class Payment
{
public string PaymentCode { get; set; }
....
}
I need to write a predicate builder that filters the PaymentCode which can be found from a list of string.
This is what I have done, but it still returns all results:
var predicate = PredicateBuilder.True<TotalPeriod>();
...// other logic
var paymentCodes = new HashSet<string>();
... // other logic to successfully get list of paymentCodes from UI
if(paymentCodes.Any())
{
predicate = predicate.And(entity => entity.SubPeriods.Any(e => e.SmallerSubPeriods.Any(e => paymentCodes.Contains(e.Payment.PaymentCode))));
}
EDIT:
generic predicate builder:
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters);
return Expression.Lambda<Func<T, bool>> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}
}
How the predicate is applied:
public async Task<ApiResponse<T>> GetManyAsync<T>(Expression<Func<TDAL, bool>> predicate, ICollection<string> includes = null) where T : class
{
try {
var expression = Expression.Convert(predicate.Body, typeof(bool));
var lambda = Expression.Lambda<Func<TDAL, bool>>(expression, predicate.Parameters);
using var dbContext = GetDatabaseContext();
var entities = await dbContext.Set<TDAL>().Where(lambda).AsNoTracking().ToArrayAsync();
... // other logic
} catch (Exception e) {
return DataProviderException.CatchException<T>(e);
}
}