实体框架 .Any 不生成预期的 SQL WHERE 子句

Posted

技术标签:

【中文标题】实体框架 .Any 不生成预期的 SQL WHERE 子句【英文标题】:Entity Framework .Any does not generate expected SQL WHERE clause 【发布时间】:2013-04-18 21:35:06 【问题描述】:

Entity Framework 和 Linq-To-Entities 真的让我有些头疼。我有一个相当简单的查询:

var result = feed.FeedItems.Any(ei => ei.ServerId == "12345");

feed 是我之前在来自同一上下文的单独查询中选择的单个 EF 实体。

但是生成的 SQL 只是丢弃了 .Any 条件,并请求提要对象的所有 FeedItems,这可能是数千条记录,这是对网络带宽的浪费。似乎是实际的。任何比较都是在 C# 中完成的:

exec sp_executesql N'SELECT [t0].[Id], [t0].[FeedId], [t0].[ServerId], [t0].[Published], [t0].[Inserted], [t0].[Title], [t0].[Content], [t0].[Author], [t0].[WebUri], [t0].[CommentsUri]
FROM [dbo].[FeedItem] AS [t0]
WHERE [t0].[FeedId] = @p0',N'@p0 int',@p0=3

我也试过了:

!feed.FeedItems.Where(ei => ei.ServerId == "12345").Any();

但它不会改变任何东西。即使删除 Any() 并查询完整的项目列表也不会改变查询。

我不明白......为什么这没有像我预期的那样工作?应该有一个

WHERE ServerId == 1234

SQL 语句中的子句。

非常感谢您的帮助/澄清:)

【问题讨论】:

什么是feed.FeedItems 如前所述,提要是从 DbContext 中查询的,因此 feed.FeedItems 是一个 EntitySet 【参考方案1】:

正如 Nicholas 已经注意到的,看起来像在 FeedItems 属性中执行的查询(可能您返回 ListIEnumerable)并且整个项目列表都从数据库返回。之后,您将 Any 应用于内存集合。这就是您在 SQL 查询中看不到 WHERE ServerId == 1234 的原因。

当您将Any 应用于IQueryable 时,生成的查询将如下所示:

SELECT 
    (CASE 
        WHEN EXISTS(
            SELECT NULL AS [EMPTY]
            [dbo].[FeedItem] AS [t0]
            WHERE [t0].[ServerId] = @p0
            ) THEN 1
        ELSE 0
     END) AS [value]

【讨论】:

现在我从数据库上下文中获取 feed 对象,如下所示: Feed feed = db.Feeds.FirstOrDefault(f => f.Id == feedId);所以 feed.FeedItems 将通过 EntitySet ...这样应该正常工作,应该吗? 哦,没关系... EntitySet 不是 IQueryable ...该死的,这是我的错误假设。非常感谢您的快速回复!

以上是关于实体框架 .Any 不生成预期的 SQL WHERE 子句的主要内容,如果未能解决你的问题,请参考以下文章

带有 Sql 视图的实体框架在生成 .sql 文件中显示为表

为啥实体框架会生成嵌套 SQL 查询?

如何获取实体框架生成的sql [重复]

如何为实体框架 Sql 提供程序编写测试并访问生成的 Sql 命令

实体框架使用 PatIndex 生成的查询不起作用

实体框架,LINQ:不能在 StartsWith 中使用 Any?