c# - 继续获取 'The LINQ expression node type ' Invoke' 在 LINQ to Entities 的异常中不受支持

标签 c# .net linq entity-framework

我正在使用 C#(包括 Linq)开发 Web 应用程序。我已经编写了一个通用方法来扩展任何实体的 Get 方法。但是,当我在执行代码时收到运行时异常“LINQ to Entities 不支持 LINQ 表达式节点类型‘Invoke’”。下面是代码:

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

有人可以告诉我我做错了什么吗?

最佳答案

您正在使用 LinqKit,它只适用于调用了 AsExpandable() 的可查询对象。这将包装底层查询提供程序并将所有对 Invoke 的调用(And 在内部使用)转换为查询提供程序可以理解的内容。

另一种方法是不使用 LinqKit,而是使用以下版本的 PredicateBuilder,它可以 And/Or 谓词表达式而不依赖于 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);
    }
}

它依赖于以下方法将一个表达式的所有实例替换为另一个表达式:

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

关于c# - 继续获取 'The LINQ expression node type ' Invoke' 在 LINQ to Entities 的异常中不受支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22406952/

相关文章:

c# - IP 地址是否与本地计算机在同一子网上(支持 IPv6)

c# - 通用 orderby 子句的动态表达式

c# - MVC3 在 ActionLink OnComplete 事件上触发多个函数?

c# - 如何将导航栏操作链接固定在右侧

c# - 是否可以限制每秒的 Web 请求数?

c# - @ 后有 2 个字符的正则表达式电子邮件

.net - 我可以在 .NET 中模拟不同 Active Directory 域上的用户吗?

javascript - 生成带有隐藏输入的表单并提交到操作

c# - 如何为 System.Core 创建外部别名?

c# - 如何在保存到数据库之前维护唯一列表? - C#