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

2

11

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);
    }
Unlisted answered 22/8, 2013 at 8:18 Comment(1)
Take a look at the updated answer (I think you already accepted it an not sure it you still get notifies in that case) that takes Florian's comment into account.Mortify
M
6

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();
}
Mortify answered 22/8, 2013 at 8:24 Comment(2)
This leaks the an not yet evaluated IQueryable which can then result in unexpected results. Because the scope of search isn't fixed to GetBySearch -> Bad PracticePersonage
@FlorianDohrendorf True. Easily fixed if you make the function return a List<Event> and return query.ToList(). Unless you really need that IQueryable that would be the way to go. I'll edit it in.Mortify
P
2

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

This would be valid:

MethodCallExpression e = query.Expression as MethodCallExpression;
Personage answered 22/8, 2013 at 8:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.