【问题标题】:LINQ predicate in Entity Framework实体框架中的 LINQ 谓词
【发布时间】:2014-05-21 10:59:49
【问题描述】:

我要调用方法

 query.Range(item => item.Date, filter.Date);

并有方法:

 public static IQueryable<T> Range<T>(this IQueryable<T> query, Func<T, DateTime> func, DateTime range)
    {
       return query.Where(item=> func(item) <= range); // <<-- Error "func(item)"
    }

错误: LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。

如何使用函数?

【问题讨论】:

  • 为什么不query.Where(item =&gt; item.Date &lt;= filter.Date)?
  • 你想的太复杂了,想的太简单了。
  • 泛型,不能使用Date。
  • 考虑将 PredicateBuilder 用于动态 where 条件。 stackoverflow.com/questions/11490893/…
  • 你想达到什么目的?

标签: c# linq entity-framework


【解决方案1】:

当你写作时

return query.Where(item => func(item) <= range);

那么 lambda item =&gt; func(item) &lt;= range 不是简单的 lambda - 它转换为 Expression&lt;Func&lt;T,bool&gt;&gt;。当您执行查询时,EF 会尝试将此类表达式转换为 SQL 代码。不幸的是,它不知道应该如何在纯 SQL 中表示 func 的调用。因此,您会看到此错误。而且您不能在传递给 EF 的表达式中使用委托调用。

解决方法:而不是

query.Range(item => item.Date, filter.Date)

使用简单(在这种情况下也更具可读性)

query.Where(item => item.Date <= filter.Date)

更新:您可以手动构建日期过滤器表达式:

public static IQueryable<T> Range<T>(this IQueryable<T> query,
    Expression<Func<T, DateTime>> func, DateTime range)
{            
    var predicate = 
        Expression.Lambda<Func<T, bool>>(
            Expression.LessThanOrEqual(func.Body, Expression.Constant(range)),
            func.Parameters.Single());

    return query.Where(predicate);
}

【讨论】:

  • 普通dll,使用泛型
  • @Sequd 更新了答案。现在您可以在任何类型上使用此扩展来按日期属性进行过滤
  • 我刚刚遇到了一个非常相似的案例,我确实以相同的方式解决了这个问题,但是我必须手动创建一个新参数,将 func 的参数替换为新参数并将其提供给生成的 lambda,否则我有一个“参数 xxx 未绑定在指定的 LINQ to Entities 查询表达式中”异常。
【解决方案2】:

您可以使用更通用的方法。

    public IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return db.Set<T>().Where<T>(predicate).AsQueryable<T>();
    }

并称之为:

query.Filter<MyClassIWantToFetch>(item => item.Date <= filter.Date)

别忘了把 MyClassIWantToFetch 改成你想要的类型。

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2017-07-07
    相关资源
    最近更新 更多