实体框架中的LINQ谓词
本文关键字:LINQ 谓词 框架 实体 | 更新日期: 2023-09-27 18:04:19
我想调用方法
query.Range(item => item.Date, filter.Date);
and have method:
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' .
如何使用函数?
当你写
return query.Where(item => func(item) <= range);
则λ item => func(item) <= range
不是简单的λ,它被转换成Expression<Func<T,bool>>
。在执行查询时,EF会尝试将这些表达式转换为SQL代码。不幸的是,它不知道func
的调用应该如何在纯SQL中表示。因此,您会看到这个错误。并且不能在传递给EF的表达式中使用委托调用。
解决方法:代替
query.Range(item => item.Date, filter.Date)
使用simple(在这种情况下也更易于阅读)
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);
}
您可以使用更通用的方法。
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更改为您想要获取的类型