Объекты C# PredicateBuilder: параметр 'f' не был связан в указанном LINQ с выражением запроса Объектов

Я должен был создать динамический фильтр, и я хотел продолжать использовать объекты. Из-за этой причины я хотел использовать 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.

Кто-либо еще столкнулся с этой ошибкой, и знайте, как решить ее?

54
задан leppie 6 January 2015 в 02:52
поделиться

1 ответ

Я столкнулся с той же ошибкой, проблема, похоже, заключалась в том, что у меня были предикаты, созданные с помощью 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, что стоит проверить.

122
ответ дан 7 November 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: