#c# #linq
#c# #linq
Вопрос:
У меня есть:
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; }
....
}
Мне нужно написать конструктор предикатов, который фильтрует те PaymentCode
, которые можно найти из списка строк.
Это то, что я сделал, но он по-прежнему возвращает все результаты:
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))));
}
Редактировать:
универсальный конструктор предикатов:
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);
}
}
Как применяется предикат:
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);
}
}
Комментарии:
1.
And()
насколько я вижу, это не стандартное расширение LINQ. Какой типpredicate
и чтоpredicate.And(...)
делает?2. @Corey Я добавил РЕДАКТИРОВАНИЕ, чтобы добавить универсальный конструктор предикатов, и метод
And()
исходит из этого3. Ваше
And()
расширение выглядит нормально. Остается сам предикат. Вы показываете, как он составлен, но не как он применяется. Где-то вам придется вызыватьWhere(...)
для фильтрации коллекции. Не могли бы вы показать этот код, пожалуйста?4. Вы хотите просто узнать, есть ли какая-либо строка, содержащая эти коды платежей, или вы хотите иметь эти объекты? Если это так, вам нужно
Where
предложение. А затем возврат abool
в предикате не имеет особого смысла5. @Link Я хочу отфильтровать объект
Payment
, которыйPaymentCode
соответствует условию