【问题标题】:Conditions in Where predicate before join vs in Where clause连接前 Where 谓词中的条件与 Where 子句中的条件
【发布时间】:2014-09-05 13:27:50
【问题描述】:

我在Entity Framwork 中加入了两个对象,并将所有条件放在Where 子句中。但是我的老板说将所有其他条件放在Where 谓词中会更有效。如下,第一个是我的版本-

var query = from ct in dbContext.ClaimTrackings
                                            join cts in dbContext.ClaimTrackingStatus
                                            on ct.ID equals cts.ClaimTrackingID
                                            where ct.CenterID == centerID && ct.ClaimMonth == SharePointClaimProcessingData.ClaimMonth && ct.ClaimYear == SharePointClaimProcessingData.ClaimYear
                                            select cts;




var query = from ct in dbContext.ClaimTrackings.Where(p => p.CenterID == centerID && p.ClaimMonth == SharePointClaimProcessingData.ClaimMonth && p.ClaimYear == SharePointClaimProcessingData.ClaimYear)
                                            join cts in dbContext.ClaimTrackingStatus
                                            on ct.ID equals cts.ClaimTrackingID
                                            select cts;

我看不到生成的脚本,因为此代码只能在生产环境中运行。 我不确定哪个更有效。所以请解释一下。

【问题讨论】:

  • 看起来它们可能会生成相同或等效的 SQL 语句 - 您是否检查过运行这些查询时生成的 SQL 语句?枚举之前发生的任何事情都将被转换为单个存储表达式,因此很可能由于这些返回相同的结果,查询/计划将是相同的。我可以为您尝试一组类似的联接
  • 查看我更新的帖子,由于某些限制,我无法在本地运行它。
  • 也许我可以创建一个示例项目并在我有时间的时候运行它。但我也想听听一些专家的意见。

标签: sql sql-server-2012 entity-framework-6


【解决方案1】:

好的,我已经做了一些测试,我认为是正确的 - 因为结果是相同的,所以将 where 子句向上移动根本没有区别 - 当然对于 SQL 服务器来说。

刚刚在我们的一个客户端应用程序的上下文中运行了这两个查询(只是将您的实体名称换成了我的):

        var query = from ct in _context.Batches
                    join cts in _context.Blends
                    on ct.BatchId equals cts.BatchId
                    where ct.BatchId == 13349 && ct.CreatedBy == "Automation"
                    select cts;

        var query2 = from ct in _context.Batches.Where(x => x.BatchId == 13349 && x.CreatedBy == "Automation")
                     join cts in _context.Blends
                     on ct.BatchId equals cts.BatchId
                     select cts;

等效查询:

SELECT 
[Extent2].[BlendId] AS [BlendId], 
[Extent2].[BatchId] AS [BatchId], 
[Extent2].[BlendNumber] AS [BlendNumber], 
[Extent2].[ProductCode] AS [ProductCode], 
[Extent2].[TargetQuantity] AS [TargetQuantity], 
[Extent2].[RecipeDescription] AS [RecipeDescription], 
[Extent2].[BlenderId] AS [BlenderId], 
[Extent2].[TestingSetDescription] AS [TestingSetDescription], 
[Extent2].[SieveDefaultDescription] AS [SieveDefaultDescription], 
[Extent2].[ReblendTime] AS [ReblendTime], 
[Extent2].[Operator] AS [Operator], 
[Extent2].[ProcessedBy] AS [ProcessedBy], 
[Extent2].[KeggedBy] AS [KeggedBy], 
[Extent2].[ApprovedBy] AS [ApprovedBy], 
[Extent2].[ActualQuantity] AS [ActualQuantity], 
[Extent2].[TestedBy] AS [TestedBy], 
[Extent2].[TestStatus] AS [TestStatus], 
[Extent2].[ApprovedQuantity] AS [ApprovedQuantity], 
[Extent2].[CreatedDate] AS [CreatedDate]
FROM  [dbo].[Batches] AS [Extent1]
INNER JOIN [dbo].[Blends] AS [Extent2] ON [Extent1].[BatchId] = [Extent2].[BatchId]
WHERE (13349 = [Extent1].[BatchId]) AND (N'Automation' = [Extent1].[CreatedBy])

SELECT 
[Extent2].[BlendId] AS [BlendId], 
[Extent2].[BatchId] AS [BatchId], 
[Extent2].[BlendNumber] AS [BlendNumber], 
[Extent2].[ProductCode] AS [ProductCode], 
[Extent2].[TargetQuantity] AS [TargetQuantity], 
[Extent2].[RecipeDescription] AS [RecipeDescription], 
[Extent2].[BlenderId] AS [BlenderId], 
[Extent2].[TestingSetDescription] AS [TestingSetDescription], 
[Extent2].[SieveDefaultDescription] AS [SieveDefaultDescription], 
[Extent2].[ReblendTime] AS [ReblendTime], 
[Extent2].[Operator] AS [Operator], 
[Extent2].[ProcessedBy] AS [ProcessedBy], 
[Extent2].[KeggedBy] AS [KeggedBy], 
[Extent2].[ApprovedBy] AS [ApprovedBy], 
[Extent2].[ActualQuantity] AS [ActualQuantity], 
[Extent2].[TestedBy] AS [TestedBy], 
[Extent2].[TestStatus] AS [TestStatus], 
[Extent2].[ApprovedQuantity] AS [ApprovedQuantity], 
[Extent2].[CreatedDate] AS [CreatedDate]
FROM  [dbo].[Batches] AS [Extent1]
INNER JOIN [dbo].[Blends] AS [Extent2] ON [Extent1].[BatchId] = [Extent2].[BatchId]
WHERE (13349 = [Extent1].[BatchId]) AND (N'Automation' = [Extent1].[CreatedBy])

不出所料,它们是相同的。我无法为您提供 EF 用于生成查询的确切机制,但基本上您正在连接两个表并进行过滤,因此转换为存储查询会为您提供相同的结果,很可能是因为它查看所涉及实体的方式

所以,在这种情况下,第二次猜测你的老板(我一直在做的事情)是正确的 :)

【讨论】:

    猜你喜欢
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 2013-08-29
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    相关资源
    最近更新 更多