2015-10-15 83 views
0

所有,優化實體框架的LINQ查詢(選擇1意外場)

誰能幫我優化下EF/Linq查詢:

的EF/Linq查詢(從LinqPad拍攝):

Articles 
    .AsNoTracking() 
    .Where(a => a.Active == "J") 
    .SelectMany(a => KerlServices 
     .Where(ks => ks.Service.SAPProductNumber == a.SAPProductNumber)) 
    .Select(ks => new { 
     ks.KerlCode, 
     ks.Service.SAPProductNumber, 
     ks.Service.Type }) 
    .ToList() 

文章與服務之間的關係(ks.Service.SAPProductNumber == a.SAPProductNumber)理論上是1:可選關係,不能在EF中定義。但是,這是而不是我的問題。

產生的SQL查詢:

SELECT 
    [Join1].[F_SERVICESID] AS [F_SERVICESID], 
    [Join1].[F_KERLCOD] AS [F_KERLCOD], 
    [Join1].[F_SAPARTNUM] AS [F_SAPARTNUM], 
    [Join1].[F_TYPE] AS [F_TYPE] 
    FROM [dbo].[T_ART] AS [Extent1] 
    INNER JOIN (SELECT [Extent2].[F_KERLCOD] AS [F_KERLCOD], [Extent2].[F_SERVICESID] AS [F_SERVICESID], [Extent3].[F_SAPARTNUM] AS [F_SAPARTNUM], [Extent3].[F_TYPE] AS [F_TYPE] 
     FROM [dbo].[T_SERVICESKERL] AS [Extent2] 
     INNER JOIN [dbo].[T_SERVICES] AS [Extent3] ON [Extent2].[F_SERVICESID] = [Extent3].[F_ID]) AS [Join1] ON [Extent1].[F_SAPARTNUM] = [Join1].[F_SAPARTNUM] 
    WHERE N'J' = [Extent1].[F_ACTIND] 

爲什麼EF產生選擇[Join1]查詢[F_SERVICESID]?我不需要這個領域。有誰知道一種方法來防止這種情況?

親切的問候,月

加入1:

KerlServices 
    .AsNoTracking() 
    .Select(ks => new { 
     ks.KerlCode, 
     ks.Service.SAPProductNumber, 
     ks.Service.Type }) 
    .Join(
     Articles, 
     ks => ks.SAPProductNumber, 
     a => a.SAPProductNumber, 
     (ks, a) => new { ks, a.Active }) 
    .Where(ksa => ksa.Active == "J") 
    .Select(ksa => ksa.ks) 
    .ToList() 

結果:

SELECT 
    [Extent1].[F_SERVICESID] AS [F_SERVICESID], 
    [Extent1].[F_KERLCOD] AS [F_KERLCOD], 
    [Extent2].[F_SAPARTNUM] AS [F_SAPARTNUM], 
    [Extent2].[F_TYPE] AS [F_TYPE] 
    FROM [dbo].[T_SERVICESKERL] AS [Extent1] 
    INNER JOIN [dbo].[T_SERVICES] AS [Extent2] ON [Extent1].[F_SERVICESID] = [Extent2].[F_ID] 
    INNER JOIN [dbo].[T_ART] AS [Extent3] ON [Extent2].[F_SAPARTNUM] = [Extent3].[F_SAPARTNUM] 
    WHERE N'J' = [Extent3].[F_ACTIND] 

這種 '改進' 不回答我的問題,但肯定的結果看起來更漂亮。

更新1:

伊萬Stoev的答案查詢生成的SQL語句:

SELECT 
    [Extent1].[F_SERVICESID] AS [F_SERVICESID], 
    [Extent1].[F_KERLCOD] AS [F_KERLCOD], 
    [Extent2].[F_SAPARTNUM] AS [F_SAPARTNUM], 
    [Extent2].[F_TYPE] AS [F_TYPE] 
    FROM [dbo].[T_SERVICESKERL] AS [Extent1] 
    INNER JOIN [dbo].[T_SERVICES] AS [Extent2] ON [Extent1].[F_SERVICESID] = [Extent2].[F_ID] 
    WHERE EXISTS (SELECT 
     1 AS [C1] 
     FROM [dbo].[T_ART] AS [Extent3] 
     WHERE (N'J' = [Extent3].[F_ACTIND]) AND ([Extent3].[F_SAPARTNUM] = [Extent2].[F_SAPARTNUM]) 
    ) 
+0

我正在用盡想法。 EF版本?數據庫類型 - Sql Server?你有沒有檢查它在VS而不是LinqPad? –

+0

@IvanStoev:好主意看看不使用LinqPad時生成的SQL。也許LinqPad是負責任的。 –

+0

查看我更新的答案。在處理另一個SO問題時,我發現了類似的情況,並且從查詢實現的角度來看完全沒有問題。 –

回答

1

爲什麼EF產生選擇[Join1]查詢[F_SERVICESID。?我不需要這個領域。

這很奇怪,如果屬實,我沒有解釋。

誰能幫我優化下EF/Linq查詢

這是值得嘗試以下,這對我來說代表檢索有問題的數據是最符合邏輯的方法:

KerlServices 
    .AsNoTracking() 
    .Select(ks => new { 
     ks.KerlCode, 
     ks.Service.SAPProductNumber, 
     ks.Service.Type }) 
    .Where(ks => Articles.Any(a => a.Active == "J" && a.SAPProductNumber == ks.SAPProductNumber) 
    .ToList() 

更新:最近我遇到過,當使用外鍵關係撥號時,EF在生成的SQL查詢中包含一些附加字段。這些字段是而不是包含在預測結果中,所以我認爲你不應該擔心。執行上面的任何查詢,在真實代碼環境(VS Debug)中執行它並檢查投影列表 - 我很確定相關字段不會在那裏。

+0

感謝您的回答。非常酷,你實際上提到了我開始優化之前的* exact *查詢。我將那個生成的SQL作爲** UPDATE 1 **添加到了我原來的問題中。 –

+0

@ JanC.deGraaf Sql查詢看起來完全是我將手寫的,除了別名和那個奇怪的列。所以無論我們做什麼,你都會得到這個'[F_SERVICEID]'。順便說一下,KerlCode屬性的類型是什麼? –

+0

「KerlCode」屬性的類型是必需的 - 字符串長度-5。在數據庫中它是'nvarchar(5),不是空'。 –