Объекты С# PredicateBuilder: параметр 'f' не был связан в указанном выражении запроса LINQ to Entities
Мне нужно было создать динамический фильтр, и я хотел продолжать использовать сущности. По этой причине я хотел использовать PredicateBuilder из albahari.
Я создал следующий код:
var invoerDatums = PredicateBuilder.True<OnderzoeksVragen>();
var inner = PredicateBuilder.False<OnderzoeksVragen>();
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 to Entities выражение.
При поиске ответа я нашел следующую страницу. Но это уже реализовано в LINQKit.
Кто-нибудь еще испытал эту ошибку и знает, как ее решить?
Ответы
Ответ 1
Я столкнулся с одной и той же ошибкой, похоже, проблема заключалась в том, что у меня были предикаты с PredicateBuilder, которые в свою очередь были составлены из других предикатов, сделанных с помощью PredicateBuilder
например. (A OR B) AND (X OR Y), где один строитель создает A OR B, создается X OR Y и третий ANDs вместе.
Только с одним уровнем предикатов 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 возвращает выражение.
Как только мы закончили ошибку, мы, безусловно, смогли создать сложные фильтры во время выполнения против структуры сущности.
Edit:
Поскольку люди по-прежнему комментируют голосование и обсуждают это, я предполагаю, что он по-прежнему полезен, поэтому я использую другое исправление. В основном я прекратил использовать LinqKit и его предиктор-строитель в пользу этого Universal Predicate Builder, который имеет тот же API, но не нуждается в разворачивании вызовов, хорошо стоит проверить.
Ответ 2
Я получил эту ошибку, и объяснение Mant101 дало мне ответ, но вы можете искать более простой пример, который вызывает проблему:
// This predicate is the 1st predicate builder
var predicate = PredicateBuilder.True<Widget>();
// and I am adding more predicates to it (all no problem here)
predicate = predicate.And(c => c.ColumnA == 1);
predicate = predicate.And(c => c.ColumnB > 32);
predicate = predicate.And(c => c.ColumnC == 73);
// Now I want to add another "AND" predicate which actually comprises
// of a whole list of sub-"OR" predicates
if(keywords.Length > 0)
{
// NOTICE: Here I am starting off a brand new 2nd predicate builder....
// (I'm not "AND"ing it to the existing one (yet))
var subpredicate = PredicateBuilder.False<Widget>();
foreach(string s in keywords)
{
string t = s; // s is part of enumerable so need to make a copy of it
subpredicate = subpredicate.Or(c => c.Name.Contains(t));
}
// This is the "gotcha" bit... ANDing the independent
// sub-predicate to the 1st one....
// If done like this, you will FAIL!
// predicate = predicate.And(subpredicate); // FAIL at runtime!
// To correct it, you must do this...
predicate = predicate.And(subpredicate.Expand()); // OK at runtime!
}
Надеюсь, это поможет!: -)