Keep Getting 'The LINQ expression node type 'Invoke' is not supported in LINQ to Entities' Exception

前端 未结 3 2203
清歌不尽
清歌不尽 2020-12-01 13:45

I am using C# (including Linq) to develop a web application. I have written a generic method to extend Get method of any entity. However when I get the runtime exception \'T

3条回答
  •  旧时难觅i
    2020-12-01 13:52

    You're using LinqKit, which will only work on queryables that have had AsExpandable() called on them. This will wrap the underlying query provider and translate all calls to Invoke (which And is using internally) into something that the query provider will understand.

    The alternative would be to simply not use LinqKit, and use the following version of PredicateBuilder that can And/Or predicate expressions without relying on the use of Invoke:

    public static class PredicateBuilder
    {
        public static Expression> True() { return f => true; }
        public static Expression> False() { return f => false; }
    
        public static Expression> Or(
            this Expression> expr1,
            Expression> expr2)
        {
            var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
            return Expression.Lambda>
                  (Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
        }
    
        public static Expression> And(
            this Expression> expr1,
            Expression> expr2)
        {
            var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
            return Expression.Lambda>
                  (Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
        }
    }
    

    It instead relies on the following method to replace all instance of one expression with another:

    public static Expression Replace(this Expression expression,
        Expression searchEx, Expression replaceEx)
    {
        return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
    }
    
    internal class ReplaceVisitor : ExpressionVisitor
    {
        private readonly Expression from, to;
        public ReplaceVisitor(Expression from, Expression to)
        {
            this.from = from;
            this.to = to;
        }
        public override Expression Visit(Expression node)
        {
            return node == from ? to : base.Visit(node);
        }
    }
    

提交回复
热议问题