2013-04-08 63 views
1

現在我有一個討厭的複雜查詢,我需要加載大量數據進行處理。數據嵌套運行相當深...簡化實體框架中的複雜包含連接

public List<agZone> agZone_GetZonesWithProjectionInformation(IEnumerable<int> ids, bool includeHidden) 
{ 
    var zones = this.BaseDB.agZones.Where(x => (includeHidden || includeHidden == x.agField.Hidden) 
           && x.agField.WeatherSourceID.HasValue 
           && x.agField.WeatherProjectionID.HasValue 
           && x.agField.SeedID.HasValue 
           && ids.Contains(x.ZoneID)) 
         .Include(x => x.agField) 
         .Include(x => x.agField.agSeed) 
         .Include(x => x.agField.agSeed.agSeedCompany) 
         .Include(x => x.agField.agSeed.agSeedConfigs) 
         .Include(x => x.agField.agSeed.agSeedGrowthStages) 
         .Include(x => x.agField.agSeed.agSeedGrowthStages.Select(y => y.agGrowthStage)) 
         .Include(x => x.agField.agFieldGrowthStages) 
         .Include(x => x.agField.agFarm) 
         .Include(x => x.agField.agFarm.agGrower) 
         .Include(x => x.agField.agFarm.agGrower.agUsers) 
         .Include(x => x.agZoneNitrogenApplications) 
         .Include(x => x.agZoneWaterApplications) 
         .Include(x => x.agSoilSymbol) 
         .Include(x => x.agSoilSymbol.agSoilConfigs) 
         .AsNoTracking(); 

    return zones.ToList(); 
} 

到目前爲止,我所知道的兩個壞的東西會在這裏:

  1. 查詢使用.Contains(...) - 實體框架5按說是不能編譯或緩存這些查詢 - 所以它們必須每次都重新生成。那很爛,但我現在沒有辦法解決它。更糟的是,在生成查詢的同時,EF似乎阻止了其他等待查詢的線程。這真的很糟糕。
  2. 這些包含大大增加了查詢的複雜性以及由於重複的主要細節而返回的數據量。生成的SQL命令長2100多行,執行計劃直接來自地獄。

有太多的數據延期加載(除了那通常是可怕的),我不知道有一種方法,使我的zones變量多次急切的加載旅行。

我是否需要進行多個查詢,然後使用foreach循環和/或LINQ將數據一起壓縮?我確實需要將所有這些數據加載到內存中,否則我的計算將會非常糟糕。到目前爲止,這實際上是我能做到的最快的。謝謝!

回答

1

另一種方法是在數據庫上創建SQL視圖,並針對該視圖執行簡單的EF映射。僅此一項就可以大大降低性能影響。

您甚至可以考慮在單獨的表格或其自己的數據存儲中創建非規格化投影。無論是在相關數據被修改時,還是作爲批處理作業,取決於您需要這些數據的頻率和時間。 CQRS可能非常適合這個特定問題。

0

我是否需要進行多個查詢,然後使用foreach循環和/或LINQ將數據一起壓縮?

是的。它可以幫助很多。許多集合會產生影響執行時間的大型連接。我遇到了同樣的問題,並通過額外的調用來填充集合。

+0

你能舉一個很好的方法來做這個例子嗎?我現在得到了一個例外,因爲'ICollection '屬性被我的DataContext處理掉了。 – jocull 2013-04-08 18:35:34

+0

我認爲它實際上與DataContext中的代理創建有關 - 我將其關閉,它不再是一個問題。 – jocull 2013-04-08 19:15:53