我正在使用 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/