Подтвердить что ты не робот

"Выражение LINQ node типа" Invoke "не поддерживается в LINQ to Entities" - stumped!

В моем EF позже я пытаюсь передать анонимную функцию, которая будет использоваться как часть моего запроса Linq. Функция передала бы INT и вернула бы BOOL (u.RelationTypeId - INT). Ниже приведен упрощенный вариант моей функции:

public IEnumerable<UserBandRelation> GetBandRelationsByUser(Func<int, bool> relation)
{
    using (var ctx = new OpenGroovesEntities())
    {
        Expression<Func<UsersBand, bool>> predicate = (u) => relation(u.RelationTypeId);

        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}

Однако я получаю ошибку, указанную выше. Кажется, я все правильно исправляю, создавая предикат из функции. Есть идеи? Спасибо.

4b9b3361

Ответ 1

Вы пытаетесь передать произвольную функцию .NET в... как может инфраструктура сущности перевести ее в SQL? Вы можете изменить его, чтобы вместо этого принять Expression<Func<int, bool>> и построить предложение Where, хотя это будет не так просто, потому что вам нужно будет переписать выражение с другим выражением параметра (т.е. заменить любой параметр выражение находится в исходном дереве выражений с выражением вызова u.RelationTypeId).

Чтобы быть честным, ради простого указания u.RelationTypeId в выражении лямбда, которое вы используете для создания дерева выражений для перехода в метод, вам лучше было бы использовать только:

public IEnumerable<UserBandRelation> GetBandRelationsByUser(
    Expression<Func<UsersBand, bool>> predicate)
{
    using (var ctx = new OpenGroovesEntities())
    {
        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}

Ответ 2

Я получал эту самую ошибку, и я использую Entity Framework с PredicateBuilder от Joe Albahari для создания динамических предложений where. Если вы оказались в одном и том же состоянии, вы должны вызвать метод AsExpandable:

Если запрос с Entity Framework, измените последнюю строку на это:

return objectContext.Products.AsExpandable().Where(predicate);

Этот метод является частью LINQKIT DLL, который вы можете захватить здесь или через пакет NuGet .

Теперь все отлично.:)

Ответ 3

Вы можете вызвать метод Развернуть() на предикате перед запросом где

Ответ 4

Я знаю, что этот ответ очень поздний, но я столкнулся с той же проблемой, и это привело меня сюда, поэтому я решил поделиться своим решением.

Я прочитал ответ Leniel, и это дало мне представление. Типы по умолчанию имеют метод "AsEnumerable()", который ведет себя одинаково, облегчая проблему.