C# 实体框架未将Where子句作为Where子句发送到SQL Server

C# 实体框架未将Where子句作为Where子句发送到SQL Server,c#,.net,entity-framework,where-clause,C#,.net,Entity Framework,Where Clause,我有一个简单的数据库,它有站点,每个站点都有一堆帖子 我试图获取某个站点的所有“公共”帖子(我有一个名为Site的变量,它已经是EF带来的一个实例) 第一件显而易见的事情是: var posts = from post in site.Posts where post.Public == true orderby post.PublicationTime descending select post; 这给

我有一个简单的数据库,它有站点,每个站点都有一堆帖子

我试图获取某个站点的所有“公共”帖子(我有一个名为Site的变量,它已经是EF带来的一个实例)

第一件显而易见的事情是:

  var posts = from post in site.Posts
              where post.Public == true
              orderby post.PublicationTime descending
              select post;
这给我带来了我想要的,但是查看SQL Server Profiler,这里只过滤公共字段,而不是站点。事实上,在SQLServer中运行Profiler捕获的查询确实会从所有站点返回所有帖子(很明显,稍后会在ASP.Net端对其进行过滤)

然后我试着:

  var posts = from post in db.Posts
              where post.Site == site && post.Public == true
              orderby post.PublicationTime descending
              select post;
同样的结果

我在做一些根本上愚蠢的事情吗?
实体框架是否总是在客户端进行过滤

谢谢

Daniel

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

当您针对ObjectContext发出查询时,您正在使用LINQ to实体。这将返回一个IQueryable。只要您使用的是IQueryable类型的变量,就可以使用LINQAPI进一步组合查询,当您最终枚举结果时,它将转换为SQL

但是你说:

(我有一个名为site的变量,它已经是EF带来的实例)

这里查询的是对象的属性,因此使用的是LINQ to对象,而不是LINQ to实体。这意味着您的查询具有不同的提供程序,并且不会转换为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
。我认为它更干净。

如果任何人在使用此方法语法时遇到问题:


如果将
Func
传递给
.Where
方法,则在查询从数据库返回后应用筛选函数。这是因为
方法的返回值返回IEnumerable。另一方面,如果你传递一个
表达式,你能发布Site/Posts类吗?我假设Public是一个布尔值,但是Site是什么类型?Site是一个模型实体,与Posts有关系,其中一个Site有很多Posts。这能回答你的问题吗?