Я должен был создать динамический фильтр, и я хотел продолжать использовать объекты. Из-за этой причины я хотел использовать PredicateBuilder от albahari.
Я создал следующий код:
var invoerDatums = PredicateBuilder.True();
var inner = PredicateBuilder.False();
foreach (var filter in set.RapportInvoerFilter.ToList())
{
if(filter.IsDate)
{
var date = DateTime.Parse(filter.Waarde);
invoerDatums = invoerDatums.Or(o => o.Van >= date && o.Tot <= date);
}
else
{
string temp = filter.Waarde;
inner = inner.Or(o => o.OnderzoekType == temp);
}
}
invoerDatums = invoerDatums.And(inner);
var onderzoeksVragen = entities.OnderzoeksVragen
.AsExpandable()
.Where(invoerDatums)
.ToList();
Когда я выполнил код был только 1 фильтр, который не был фильтром даты. Таким образом, только внутренний предикат был заполнен. Когда предикат выполнялся, я получил следующую ошибку.
Параметр 'f' не был связан в указанном LINQ с выражением запроса Объектов.
При поиске ответа я нашел следующую страницу. Но это уже реализовано в LINQKit.
Кто-либо еще столкнулся с этой ошибкой, и знайте, как решить ее?
Я столкнулся с той же ошибкой, проблема, похоже, заключалась в том, что у меня были предикаты, созданные с помощью PredicateBuilder, которые, в свою очередь, были составлены из других предикатов, созданных с помощью PredicateBuilder
, например. (A OR B) AND (X OR Y), где один строитель создает A OR B, один создает X OR Y, а третий объединяет их вместе.
Только с одним уровнем предикатов AsExpandable работал нормально, когда вводилось более одного уровня, я получал ту же ошибку.
Мне не удалось найти никакой помощи, но методом проб и ошибок я смог заставить все работать. Каждый раз, когда я вызывал предикат, я следовал за ним методом расширения Expand.
Вот фрагмент кода, сокращенный для простоты:
public static IQueryable<Submission> AddOptionFilter(
this IQueryable<Submission> query,
IEnumerable<IGrouping<int, int>> options)
{
var predicate = options.Aggregate(
PredicateBuilder.False<Submission>(),
(accumulator, optionIds) => accumulator.Or(ConstructOptionMatchPredicate(optionIds).Expand()));
query = query.Where(predicate.Expand());
return query;
}
Query - это IQueryable, для которого уже был вызван AsExpandable, ConstructOptionNotMatchPredicate возвращает выражение.
Как только мы справились с ошибкой, мы, безусловно, смогли создать сложные фильтры во время выполнения в соответствии с структурой сущностей.
Редактировать:
Поскольку люди все еще комментируют и голосуют, я полагаю, что это все еще полезно, поэтому я делюсь другим исправлением. По сути, я перестал использовать LinqKit и его построитель предикатов в пользу этого Универсального построителя предикатов , который имеет тот же API, но не требует вызовов Expand, что стоит проверить.