2016-06-28 59 views
1

我正在嘗試通過舊項目嘗試使它們更快。我目前正在查看一些Web API。一個API運行速度特別慢,問題在於它所調用的數據服務。具體來說,它是在試圖將存儲過程結果映射到域模型的lambda方法中。代碼的簡單版本。實體框架存儲過程結果到域模型

public IEnumerable<DomainModelResult> GetData() 
{ 
    return this.EntityFrameworkDB.GetDataSproc().ToList() 
      .Select(sprocResults=>sprocResults.ToDomainModelResult()) 
      .AsEnumerable(); 
} 

這是一個簡化的版本,但在分析它之後,我發現主要的掛斷是在lambda函數中。我假設這是因爲EFContext仍然是開放的,一些愚蠢的實體框架的東西正在發生。

問題是我對實體框架(實習生)比較陌生,對其內部工作原理相當陌生。有人可以解釋爲什麼這是如此緩慢。我覺得它應該非常快DomainModelResult是一個POCO,在ToDomainModelResult中只使用setter方法。

編輯: 我以爲ToList()會這樣做,但開始懷疑自己,因爲我想不出另一種解釋。所有的ToDomainModelResult()東西都非常簡單。就像是。

public static DomainModelResult ToDomainModelResult(SprocResult source) 
{ 
    return new DomainModeResult 
    { 
    FirstName = source.description, 
    MiddleName = source._middlename, 
    LastName = source.lastname, 
    UserName = source.expr2, 
    Address = source.uglyName 
    }; 
} 

它只是一堆簡單的setter,我認爲造成問題的模型有17個屬性。之所以這樣做是因爲該項目首先是舊數據庫,而存儲過程的名稱根本不具描述性。同樣,切換數據服務中的存儲過程也很容易,並且不會影響項目的其他部分。

編輯:2出於某種原因使用ToArray並拆分linq語句使得從過程結果到域模型的賦值結果非常快。現在整個dataservice方法更快,這很奇怪,我不知道剩下的時間去了哪裏。

這可能是一個比我原先想象的更深奧的問題。我的問題沒有得到解答,但問題不再存在。感謝所有答覆。我保持這個目前沒有答案。

編輯3:請將此問題標記爲刪除我無法刪除它。我發現了這個問題,但與我原來的問題完全無關。當我問這個問題時,我誤解了這個問題。速度的增加我正忙於編譯器優化和在分析器中運行代碼。真正的問題不在我的lambda中,而是在關閉上下文或訪問對象時由實體框架調用的動態lambda中進行數據驗證。 GetString,GetInt32和ISDBNull在吃飯時間最多。所以我假設微軟已經優化了這些方法,並且加速這種方法的唯一方法可能會使某些變量在程序中不可空。這個問題是誤導性的,如此深奧,我不認爲它屬於這裏,只會混淆人們。抱歉。

+0

。如果問題出現在lambda中,那麼它可能與ToDomainModelResult()有關,而不是EF中的任何東西。你可以顯示該方法的代碼? –

回答

1

你應該拆分代碼並檢查哪一個花費時間。

public IEnumerable<DomainModelResult> GetData() 
{ 
    var lst = this.EntityFrameworkDB.GetDataSproc().ToList(); 
    return lst 
      .Select(sprocResults=>sprocResults.ToDomainModelResult()) 
      .AsEnumerable(); 
} 

我很確定GetDataSproc程序佔用了大部分時間。你需要優化存儲過程的代碼

更新 如果可能的話,最好是做SQL側,而不是檢索60000行更多的工作到你的記憶。一些可能的解決方案:

  • 如果需要顯示該信息,做分頁(頂部和跳過)
  • 如果你正在做的任何過濾或計算或者你在內存中檢索行後分組什麼,做在你的存儲過程
  • 淨面,因爲你正在返回IEnumerable您可能能夠在你的第二個部分使用yield,只要你調用ToList()執行SQL查詢和完整取決於你的架構
+0

我認爲存儲過程也是所有的時間,但使用.net分析器它說存儲過程大約需要四分之一秒,而lambda大約需要10個。 – Tenderdude

+0

我將分割並檢查秒錶無論如何,但在SQL管理器上運行該過程似乎相當快。 – Tenderdude

+0

我們在談論多少行? – MJK