是否可以获得IQueryable<>;应用谓词时从EF集合返回
本文关键字:谓词 应用 返回 集合 EF gt lt IQueryable 是否 | 更新日期: 2023-09-27 18:25:50
它似乎返回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
。
有简单的解决方法吗?
问题是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;
predicate
参数应该是Expression<Func<Cat, bool>>
,而不仅仅是Func<Cat, bool>
。
这样,将返回IQueryable,因为您将使用Queryable.Where而不是Enumerable.Where.
在调用方法时,仍然可以使用lambda表达式:编译器知道如何将lambda转换为表达式。