I want to call method
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)"
}
Error: The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
How to use function?
When you write
return query.Where(item => func(item) <= range);
Then lambda item => func(item) <= range
is not simple lambda - its converted to Expression<Func<T,bool>>
. When you are executing query, EF tries to convert such expressions into SQL code. Unfortunately it does not know how invocation of func
should be represented in plain SQL. Thus you see this error. And you cannot use delegate invocations in expressions which you pass to EF.
Workaround: Instead of
query.Range(item => item.Date, filter.Date)
use simple (it's also more readable in this case)
query.Where(item => item.Date <= filter.Date)
UPDATE: You can to build date filter expression manually:
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);
}
You can use a more generic approch.
public IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate) where T : class
{
return db.Set<T>().Where<T>(predicate).AsQueryable<T>();
}
and call it:
query.Filter<MyClassIWantToFetch>(item => item.Date <= filter.Date)
and dont forget to change MyClassIWantToFetch to the type you want to get.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.