这是我的DataAccessLayer的工作方式:
public Foo GetFooBy(Func<Foo, bool> filter)
{
var query = from item in this.DataService.FooSet select item;
var where = query.Where(filter);
var first = where.First();
return first;
}
我假设查询将在调用First()时运行,但实际上是由Where()执行的。从MSDN开始,我意识到.Where(Func)是Enumerable定义的扩展方法,因此这很有意义,但我不知道它与用lambda表达式调用.Where()有何不同。
确保.Where()实现数据的一种非常简单的方法是检查查询的,where的和first的类型。
查询是IQueryable,这意味着数据库中什么都没有发生
IEnumerable在哪里,表示数据已实现*
首先是Foo
调试和SQL跟踪也非常清楚地表明数据是由.Where()获取的
编辑:*可能不正确,因为IQueryable实现IEnumerable
最佳答案
Enumerable.Where
和Queryable.Where
之间有一个非常重要的区别:Enumerable.Where
取一个Func<T, bool>
。Queryable.Where
取一个Expression
。
您的filter
变量不是Expression
,而是Func<T, bool>
,因此,编译器使用Enumerable.Where
。
然后,将FOO
表的所有行都传输到客户端,然后在内存中进行过滤。
正如其他人正确指出的那样,执行仍然发生在对First()
的调用上。
更新:
您的SQL跟踪不能证明对Where
的调用发生了实现。它仅证明Where
的过滤未在服务器端发生。上面我在回答中对此做了解释。
怎么修:
您可以通过将方法改为采用表达式来轻松解决此问题:
public Foo GetFooBy(Expression<Func<Foo, bool>> filter)
{
var query = from item in this.DataService.FooSet select item;
var where = query.Where(filter);
var first = where.First();
return first;
}
关于c# - 为什么带有Func参数的.Where()执行查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30847526/