2

所以我一直在挖掘 EF 为我们的应用程序生成的查询,我注意到一些奇怪的 sql 生成Any调用 - 它们似乎过于复杂。Any似乎生成case when (x) then 1 when (not x) then 0 end- 为什么不使用其他?这样 SQL server 必须在Any应该返回的情况下执行两次相同的查询false。我想出了在那些使用 的情况下似乎更快的解决方法Where(cond).Select(q => true).FirstOrDefault(),但我仍然对这是否只是疏忽或它有一些我遗漏的意义感兴趣。

context.Books.Any(b => b.Id == bookId);

declare @p__linq__0 Int = 1;

SELECT 
CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [Books] AS [Extent1]
    WHERE [Extent1].[ID] = @p__linq__0
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
    1 AS [C1]
    FROM [Books] AS [Extent2]
    WHERE [Extent2].[ID] = @p__linq__0
)) THEN cast(0 as bit) END AS [C1]
FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]

context.Books.Where(b => b.ID == bookId).Select(b => true).FirstOrDefault();

declare @p__linq__0 Int = 1;

SELECT TOP (1) 
cast(1 as bit) AS [C1]
FROM [Books] AS [Extent1]
WHERE [Extent1].[ID] = @p__linq__0
4

1 回答 1

1

在您看到某物不存在之后,很明显它确实不存在,因此没有必要检查 agin 是否真的不存在。这只是 linq 产生过于复杂的查询的情况之一。您的解决方法有效,但它不一定像人们希望的那样容易理解,因此我建议将原始 linq 的性能降低,直到它真正成为性能问题。只需确保在 Id 列上有一个索引。

于 2013-01-28T14:48:58.173 回答