Entity Framework没有将Where子句作为WHERE子句发送到SQL Server。
Entity Framework没有将Where子句作为WHERE子句发送到SQL Server。
我有一个简单的数据库,其中包含站点,每个站点都有一堆帖子。
我想获取特定站点的所有“公开”帖子(我已经有一个名为site的变量,它已经是由EF带来的实例)。
首先显而易见的是:
var posts = from post in site.Posts where post.Public == true orderby post.PublicationTime descending select post;
这给我带来了我想要的结果,但是通过查看SQL Server Profiler,WHERE仅仅过滤了Public字段,而没有过滤Site字段。实际上,在SQL Server中运行Profiler捕获的查询确实将所有站点的所有帖子都带了回来(这显然在ASP.Net端稍后被过滤了)。
然后我尝试了:
var posts = from post in db.Posts where post.Site == site && post.Public == true orderby post.PublicationTime descending select post;
结果一样。
我在这里做了什么基本愚蠢的事情吗?
Entity Framework总是在客户端过滤吗?
谢谢!
Daniel
问题的出现原因是因为LINQ to Objects和LINQ to Entities的区别。当对ObjectContext发出查询时,实际上是在使用LINQ to Entities。这将返回一个IQueryable对象。只要您使用的是IQueryable类型的变量,就可以使用LINQ API进一步组合查询,并且在最终枚举结果时,它将转换为SQL语句。
但是您说:
(我有一个已经由EF带来的名为site的变量)
在这里,您正在查询对象的属性,因此您实际上是在使用LINQ to Objects,而不是LINQ to Entities。这意味着您的查询具有不同的提供程序,不会转换为SQL语句。
对于您的第二个查询:
var posts = from post in db.Posts where post.Site == site && post.Public == true orderby post.PublicationTime descending select post;
EF不允许您在L2E中对实例进行身份比较。您必须比较键而不是实例。请尝试:
var posts = from post in db.Posts where post.Site.Id == site.Id && post.Public orderby post.PublicationTime descending select post;
顺便说一下,我将post.Public == true
更改为post.Public
。我认为这样更清晰。
Entity Framework不会将Where子句作为WHERE子句发送到SQL Server的问题的原因是,当将Func
解决方法是使用Expression
以下是IEnumerable和IQueryable的区别:
- IEnumerable接口表示一个泛型集合,它是一个只能在内存中操作的序列。当您在查询中使用IEnumerable时,查询将在内存中执行。
- IQueryable接口表示一个可查询的数据源,它可以在内存中执行,也可以将查询转换为SQL语句并在数据库中执行。当您在查询中使用IQueryable时,查询将被转换为SQL语句并发送到数据库。
您可以在以下链接中了解更多关于IEnumerable和IQueryable的信息:
- IEnumerable Where: https://msdn.microsoft.com/en-us/library/bb549418(v=vs.110).aspx
- IQueryable Where: https://msdn.microsoft.com/en-us/library/bb535040(v=vs.110).aspx