2013-08-22 116 views
8

我只是想构建一个动态过滤器。 最后返回如何将IQueryable <T>转换为表达式<Func <T, bool>>?

Expression<Func<Event, bool>> 

我试图使用合并(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); 
    } 
+0

看看更新答案(我认为你已经接受了它,不知道你是否仍然会通知该情况),这需要考虑Florian的评论。 – Sam

回答

6

任何理由,你不只是做到以下几点:

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

正如弗洛里安在评论中所说,返回IQueryables是可以避免的(如果可能的话)。最简单的办法是返回一个列表,而不是:

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

噢,这真的很容易,现在它的工作原理,非常感谢你:) –

+0

这泄漏了尚未评估的IQueryable,然后可能会导致意想不到的结果。由于“搜索”的范围不固定到“GetBySearch” - >错误实践 – LunicLynx

+1

@FlorianDohrendorf真。如果你让函数返回'List '和'return query.ToList()',很容易修复。除非你真的需要IQueryable,否则这将是一条路。我会编辑它。 – Sam

2

这种转换是无效的,因为Where将其转换成MethodCallExpression

这将是有效的:

MethodCallExpression e = query.Expression as MethodCallExpression; 
相关问题