4

It appears to return IEnumerable rather than IQueryable:

method parameter: Func<Cat, bool> predicate

code:

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

This doesn't compile because .Where returns IEnumerable instead of IQueryable. I know I can do .AsQueryable or whatever but I suspect that won't treat it as a proper IQueryable.

Is there a simple fix for this?

4

2 回答 2

2

predicate参数应该是一个Expression<Func<Cat, bool>>,而不仅仅是一个Func<Cat, bool>

这样,您获得 IQueryable,因为您将使用Queryable.Where而不是 Enumerable.Where。

调用方法时仍然可以使用 lambda 表达式:编译器知道如何将 lambda 转换为 Expression。

于 2014-10-07T09:54:47.007 回答
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;
于 2014-10-07T09:57:02.080 回答