如何将IQueryable<T>转换为Expression<Func<T, bool>>?

10

我只想建立一个动态筛选器。 最后返回结果。

 Expression<Func<Event, bool>>

我曾试过使用Combine (AndAlso)表达式,但它没有起作用,最终我发现有IQueryable查询可以很好地工作,但现在该如何将其转换为返回类型 -

Expression<Func<Event, bool>>?

我的代码:

    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);
    }

请查看更新的答案(我认为您已经接受了它,不确定在这种情况下是否仍会收到通知),该答案考虑了Florian的评论。 - Sam
2个回答

7
你为什么不直接执行以下操作呢:
任何原因你不直接这样做:
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;
}

正如Florian在评论中所说,尽可能避免返回IQueryable。简单的解决方案是返回一个列表:

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();
}

哦,那真的很容易,现在它可以工作了,非常感谢 :) - Misha Zaslavsky
这会泄露一个尚未评估的IQueryable,可能导致意外结果。因为search的范围不限于GetBySearch,所以这是一种不好的做法。 - LunicLynx
1
@FlorianDohrendorf 确实。如果您使函数返回 List<Event> 并且 return query.ToList(),那么很容易解决。除非您真的需要 IQueryable,否则这是正确的方法。我会进行编辑。 - Sam

2

这个转换无效,因为 Where 将其转换成了一个 MethodCallExpression

以下转换是有效的:

MethodCallExpression e = query.Expression as MethodCallExpression;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接