2010-02-11 109 views
4

我有一个简单的数据库具有站点,并且每个站点都有一堆邮件。实体框架不发送Where子句作为WHERE子句SQL Server

我试图得到一定的站点(我有一个变量,名为网站已经是EF带来的一个实例)

第一个明显的事情是所有“公共”的帖子:

var posts = from post in site.Posts 
       where post.Public == true 
       orderby post.PublicationTime descending 
       select post; 

这给我带来了我想要的东西,但看着SQL Server Profiler,WHERE只是过滤Public字段,而不是过滤网站。实际上,在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

+0

你能后的网站/帖子班? – 2010-02-11 02:52:15

+0

我假设Public是一个布尔值,但是Site是什么类型? – 2010-02-11 02:53:51

+0

网站是一个模型实体,与帖子的关系,其中一个网站有很多帖子 – 2010-02-11 02:56:48

回答

7

您需要了解LINQ to Entities和LINQ to Objects之间的区别。在使用实体框架时跟踪这一点非常重要。

当您针对ObjectContext发出查询时,则您正在使用LINQ to Entities。这将返回一个IQueryable。只要您使用IQueryable类型的变量,您可以使用LINQ API进一步编写查询,并且当您最终枚举结果时,它将转换为SQL。

但是你说:

(我有一个网站名为变量已经是EF带来的一个实例)

这里您要查询的对象的属性,让你的工作在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; 

BTW,我改变post.Public == truepost.Public。我认为它更干净。如果你传递一个Func<TEntity,Boolean>.Where方法,过滤器的功能是从数据库查询返回后应用

3

如果任何人有这种使用方法的语法有问题。这是因为.Where方法的返回值返回一个IEnumerable。另一方面,如果您将Expression<Func<TEntity,Boolean>传递给.Where方法,则筛选器函数会生成发送到数据库的where子句。这是因为.Where返回一个IQueryable。只要你坚持使用IQueryables,你就构建了发送到数据库的查询。当您返回一个IEnumerable时,使用该方法之前的所有内容创建查询,并将IEnumerable之后的所有内容应用于返回的内容。如果您将lambda函数存储在一个变量中,这才真正重要。如果您将lambda直接传递给.Where方法,则通常不会有问题。希望这可以帮助!!

的IEnumerable其中:https://msdn.microsoft.com/en-us/library/bb549418(v=vs.110).aspx

的IQueryable其中:https://msdn.microsoft.com/en-us/library/bb535040(v=vs.110).aspx