不断收到“的LINQ EX pression节点类型”调用“不支持LINQ到实体”异常 [英] Keep Getting 'The LINQ expression node type 'Invoke' is not supported in LINQ to Entities' Exception

查看:216
本文介绍了不断收到“的LINQ EX pression节点类型”调用“不支持LINQ到实体”异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用C#(包括LINQ)来开发Web应用程序。我写了一个通用的方法来扩展任何实体的Get方法。然而,当我得到的运行时异常调用不支持LINQ到实体执行code当'的LINQ EX pression节点类型。下面是code:

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 'The LINQ expression node type 'Invoke' is not supported in LINQ to Entities' when the code is executed. Below is the code:

using System.Linq;
using System.Linq.Expressions;
using LinqKit;

public static class ServiceExtension
{
    public static IEnumerable<T> GetActive<T>(this ICrudService<T> crudService, Expression<Func<T, bool>> where)
        where T : class, IDeletable
    {
        return crudService.Get(where.And(w => !w.IsDeleted));
    }
}

有人能告诉我什么,我做错了什么?

Can someone please tell me what I am doing wrong?

推荐答案

您正在使用LinqKit,这将仅适用于那些有 AsExpandable()呼吁queryables他们。这将包装的基本查询提供并翻译所有调用调用(其中用内部)弄成了查询供应商就明白了。

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.

另一种方法是根本就没有使用LinqKit,并使用predicateBuilder以下的版本,可以与/或predicate EX pressions不依赖于使用的调用

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<Func<T, bool>> True<T>() { return f => true; }
    public static Expression<Func<T, bool>> False<T>() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(
        this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2)
    {
        var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
        return Expression.Lambda<Func<T, bool>>
              (Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(
        this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2)
    {
        var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
        return Expression.Lambda<Func<T, bool>>
              (Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
    }
}

相反,它依赖于下面的方法来取代一个EX pression所有的实例与另一:

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);
    }
}

这篇关于不断收到“的LINQ EX pression节点类型”调用“不支持LINQ到实体”异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆