似乎返回IEnumerable而不是IQueryable:
方法参数:Func<Cat, bool> predicate
代码:
var allCats = _catEntities.GetCats(); // IQueryable
if (skip.HasValue) allCats = allCats .Skip(skip.Value);
if (take.HasValue) allCats = allCats .Take(take.Value);
if (predicate != null)
{
allCats = allCats.Where(predicate);
}
这不会编译,因为.Where
会返回IEnumerable
而不是IQueryable
。我知道我可以.AsQueryable
或其他什么,但我怀疑它不会被视为正确的IQueryable
。
对此有简单的解决方法吗?
答案 0 :(得分:2)
predicate
参数应该是Expression<Func<Cat, bool>>
,而不仅仅是Func<Cat, bool>
。
这样你将获得IQueryable,因为你将使用Queryable.Where而不是Enumerable.Where。
在调用方法时,您仍然可以使用lambda表达式:编译器知道如何将lambda转换为Expression。
答案 1 :(得分:2)
问题是Func<Cat, bool>
已经编译为.NET代码,因此无法在.NET进程之外执行。
因此,为了将谓词应用于allCats
,必须执行allCats
在此时定义的查询。正如您所推测的那样,使用AsQueryable
只会包装返回的IEnumerable
枚举。
如果希望LINQ提供程序翻译和执行谓词,则可以使用Expression<Func<Cat, bool>>
。请注意,这将在IQueryable
实现和谓词定义之间引入耦合。 (因为谓词必须是可以由LINQ提供程序执行的东西)。
使用lambda表达式,可以非常简单地定义Expression<Func<Cat, bool>>
:
Expression<Func<Cat, bool>> predicateExpression = c => c.Gender == Gender.Male;