2017-04-20 182 views
0

我在我的ASP.NET MVC應用程序中使用實體框架,並且在通過LINQ從SQL Server加載數據時遇到了一個問題。我的查詢在4秒內返回結果,但我需要花更少的時間,仍然尋找更好的解決方案。如何減少Entity Framework Linq查詢執行時間?

這裏是我的LINQ查詢:

var user = 
    context.CreateObjectSet<DAL.ProductMaster>() 
     .AsNoTracking() 
     .Include("Product1").AsNoTracking() 
     .Include("Product2").AsNoTracking() 
     .Include("Product3").AsNoTracking() 
     .Include("Product4").AsNoTracking() 
     .Include("Product5").AsNoTracking() 

     .Where(x => x.Id == request.Id) 
     ).FirstOrDefault(); 
+5

您是否嘗試過加載較少的實體? – Marco

+0

檢查您是否在Id和OrganizationId上創建了索引。索引可以加速這種情況。 – Tony

+3

您確定需要_ALL_這些其他表和數據,因爲這將產生相當多的JOIN操作,這可能會很昂貴。此外,你可以用'FirstOrDefault()'替換你的'Where()'子句來清理一些東西,你可能不需要爲每個Include()調用AsNoTracking()函數。 –

回答

0

無需獲得多個實體履行謂語Where()只有然後選擇第一個;直接撥打FirstOrDefault()即可。

if (request == null || organizationsList == null || !organizationsList.Any()) 
    return; 

var user = context.CreateObjectSet<DAL.User>() 
        .AsNoTracking() 
        .Include("UsersinPrograms.FollowUps") 
        .Include() ... 
        .FirstOrDefault(x => x.Id == request.userId && organizationsList.Contains(x.OrganizationId))); 

此外,請刪除您不需要的Include()

+0

感謝您的代碼,運氣很好,得到了和我以前的結果一樣的結果。 – Surendar

+0

'context.CreateObjectSet ().AsNoTracking()'...似乎很奇怪,你不想要像'context.Users..AsNoTracking()'...這樣的東西嗎?你的用戶應該已經被創建,現在你正在查詢/過濾現有的數據(而不是創建新的數據庫)。或者,這可能只是一個命名不清的方法? – Fredrik

+0

似乎它必須啓動表結構,所以不能 – Surendar

0

對於這個和任何大規模的業務邏輯操作,應該創建存儲過程而不是將它們放在Linq中。然後在EF中創建一個DTO對象來處理結果並消耗EF中的過程。

在這一點上,獲得或丟失的速度取決於程序的sql的結構,並關注數據庫中使用的索引以提高速度。

Linq SQL實際上是樣板文件,不是爲速度而設計的。

我已經完成了多個EF項目。


另外一個可以建立在Linqpad其LINQ查詢,然後切換到查看生成的SQL。這將提供一個關於如何在存儲過程中構建一個SQL的想法。

另外,您可以考慮使用SQL CTE(公共表Experssions)一次構建您的查詢,直到數據正好滿足需要。

+0

感謝您的指示,以前曾嘗試在存儲過程和視圖,但由於過多的聯接無法獲得預期的結果。這就是爲什麼尋找修復在EF中。 – Surendar

+0

@Surendar我會在Linqpad中構建我的linq查詢,然後切換到查看生成的SQL。這會給我一個關於如何在存儲過程中構建SQL的想法。你也可以考慮使用SQL CTE來一次構建你的查詢,直到數據正好滿足需要。 HTH – OmegaMan

+0

OmegaMan,這是有道理的,將在Linqpad嘗試這個,謝謝。 – Surendar