Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert IQueryable<T> to Expression<Func<T, bool>>?

I just want to build a dynamic filters. And finally to return

 Expression<Func<Event, bool>>

I've tried to use the Combine (AndAlso) expressions, but it wasn't workin and finally I found that there are IQueryable queries which works good, but now how can I convert it to the return type -

Expression<Func<Event, bool>>?

My code:

    public IQueryable<Event> GetBySearch(EventFilter search)
    {
        IQueryable<Event> query = this.Context.Events.AsQueryable();
        Expression<Func<Event, bool>> expression = null;

        if (search.CategoryId != 0)
        {
            query = query.Where(x => x.CategoryId == search.CategoryId);
        }

        if (search.SubCategoryId != 0)
        {
            query = query.Where(x => x.SubCategoryId == search.SubCategoryId);
        }

        expression = query.Expression as Expression<Func<Event, bool>>; //This convert is not working, it returns null.

        return this.Context.Events.Where(expression);
    }
like image 393
Misha Zaslavsky Avatar asked Aug 22 '13 08:08

Misha Zaslavsky


2 Answers

Any reason you don't just do the following:

public IQueryable<Event> GetBySearch(EventFilter search)
{
    IQueryable<Event> query = this.Context.Events.AsQueryable();

    if (search.CategoryId != 0)
    {
        query = query.Where(x => x.CategoryId == search.CategoryId);
    }

    if (search.SubCategoryId != 0)
    {
        query = query.Where(x => x.SubCategoryId == search.SubCategoryId);
    }

    return query;
}

As Florian said in the comment, returning IQueryables is to be avoided (when possible). The easy solution is to return a list instead:

public List<Event> GetBySearch(EventFilter search)
{
    IQueryable<Event> query = this.Context.Events.AsQueryable();

    if (search.CategoryId != 0)
    {
        query = query.Where(x => x.CategoryId == search.CategoryId);
    }

    if (search.SubCategoryId != 0)
    {
        query = query.Where(x => x.SubCategoryId == search.SubCategoryId);
    }

    return query.ToList();
}
like image 71
Sam Avatar answered Nov 17 '22 01:11

Sam


This conversion is not valid because Where converts it into a MethodCallExpression

This would be valid:

MethodCallExpression e = query.Expression as MethodCallExpression;
like image 2
LunicLynx Avatar answered Nov 17 '22 03:11

LunicLynx