8

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

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

第一个明显的事情是:

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

这给我带来了我想要的东西,但是查看 SQL Server Profiler,WHERE 只过滤公共字段,而不是站点。事实上,在 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;

结果相同。

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

谢谢!
丹尼尔

4

2 回答 2

10

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

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

但是你说:

(我有一个名为 site 的变量,它已经是 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;

顺便说一句,我post.Public == true改为post.Public. 我认为它更清洁。

于 2010-02-11T14:00:00.957 回答
6

如果有人对此使用方法语法有疑问:

如果将 a 传递Func<TEntity,Boolean>给该.Where方法,则在查询从数据库返回后应用过滤器函数。这是因为该.Where方法的返回值返回一个 IEnumerable。另一方面,如果您将 an 传递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

于 2017-01-31T16:21:24.537 回答