2017-06-05 117 views
1

我想知道爲什麼生成的SQL是檢查零位上的列,它是不可爲空(列Value這是一個非空浮)EF6產生不需要的SQL查詢

var query = _context.Events 
    .Select(e => new 
    { 
    eventId = e.EventId, 
    data = e.Data.Take(10).Select(x => new 
    { 
     name = x.Name, 
     value = Math.Round(x.Value,1), 
    }) 
    }); 

生成以下SQL代碼:

SELECT 
    [Project2].[EventId] AS [EventId], 
    [Project2].[DeviceId] AS [DeviceId], 
    [Project2].[TimeEnd] AS [TimeEnd], 
    [Project2].[C2] AS [C1], 
    [Project2].[EventId1] AS [EventId1], 
    [Project2].[Name] AS [Name], 
    [Project2].[C1] AS [C2] 
    FROM (SELECT 
     [Limit1].[EventId] AS [EventId], 
     [Limit1].[TimeEnd] AS [TimeEnd], 
     [Limit1].[DeviceId] AS [DeviceId], 
     [Extent2].[Name] AS [Name], 
     [Extent2].[EventId] AS [EventId1], 
     CASE WHEN ([Extent2].[Value] IS NULL) THEN CAST(NULL AS float) ELSE ROUND([Extent2].[Value], 1) END AS [C1], 
     CASE WHEN ([Extent2].[Value] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2] 
     FROM (SELECT [Project1].[EventId] AS [EventId], [Project1].[TimeEnd] AS [TimeEnd], [Project1].[DeviceId] AS [DeviceId] 
      FROM (SELECT 
       [Extent1].[EventId] AS [EventId], 
       [Extent1].[TimeEnd] AS [TimeEnd], 
       [Extent1].[DeviceId] AS [DeviceId] 
       FROM [dbo].[Events] AS [Extent1] 
       WHERE ([Extent1].[DeviceId] = 1) 
      ) AS [Project1] 
      ORDER BY [Project1].[TimeEnd] DESC) AS [Limit1] 
     LEFT OUTER JOIN [dbo].[Octaves] AS [Extent2] ON [Limit1].[EventId] = [Extent2].[EventId] 
    ) AS [Project2] 
    ORDER BY [Project2].[TimeEnd] DESC, [Project2].[EventId] ASC, [Project2].[C2] ASC 

如果我卸下兩個CASE WHEN ([Extent2].[Value] IS NULL)和剛剛離開ROUND([Limit2].[Value], 1) AS [C1]並刪除SQL Server管理的ORDER BY Project2].[C2] ASC查詢加快。

+0

在你的EF模型中,你應該檢查字段是否可以爲空。 –

+0

@teocomi \t 如果按原樣運行,查詢需要多長時間?如果你然後刪除CASE?如果您隨後刪除CASE和訂單? – mjwills

回答

2

有一個LEFT OUTER JOIN,所以值(在查詢中)肯定可以是NULL(即使基礎表定義不可爲空)。

請參閱http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj18922.html(對於Oracle - 但所有主要SQL供應商都適用相同的基本模式)。

在這種情況下,由於ROUND(NULL,1)無論如何都會返回NULL(它在SQL Server上),所以它有點沒有意義。但是,由於無法控制其生成的SQL,因此您無法做到這一點。