【问题标题】:Entity Framework not sending Where clauses as WHERE clauses to SQL Server实体框架未将 Where 子句作为 WHERE 子句发送到 SQL Server
【发布时间】:2011-01-15 13:28:59
【问题描述】:

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

我正在尝试获取某个站点的所有“公共”帖子(我有一个名为 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;

同样的结果。

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

谢谢!
丹尼尔

【问题讨论】:

标签: c# .net entity-framework where-clause


【解决方案1】:

您需要了解 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。我认为它更清洁。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-12-31
      • 2011-10-21
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多