我有一個問題,我認爲很多專業開發人員會遇到這個問題。我的工作場所採用了實體框架。我們使用它,並且喜歡它。但是,我們似乎遇到了一個非常令人沮喪的侷限。實體框架 - 高效的渴望加載與依賴對象的長鏈?
讓我們假設你有一個對象鏈等
甲 - >乙 - 「ç - > d
我們專業,所以這些對象有大量的數據,而且有很多的他們在他們各自的數據庫表中。看起來EF有一個可怕的時間加載任何超過對象B的東西。它生成的SQL查詢效率並不高。呼叫會像
context.objects.include("bObjectName.cObjectName.dObjectName").FirstOrDefault(x => x.PK == somePK);
我們已經明確地加載對象過去與.Load()命令第二級解決此得到。這適用於單個對象。但是,當我們談論對象集合時,我們開始遇到與.Load()相關的問題。
首先,有沒有似乎是保留對象的代理跟蹤集合中沒有虛擬關鍵字的方式。這很有意義,因爲它需要覆蓋get和set函數。但是,這會啓用延遲加載,並且.Load()在啓用延遲加載時不會映射實體。我覺得自己有點奇怪。如果刪除虛擬關鍵字,.Load()會自動將加載的對象鏈接到上下文中的相關對象。
因此,這裏是我的問題的癥結所在。我想要代理跟蹤,但也想.Load()爲我導航的屬性。如果EF可以產生好的查詢,這些都不是問題。我明白爲什麼它不能,它必須是一個適合所有類型的東西。
所以加載對象的二三線我也許可以在我的服務層裝載函數,它接受對象的第二層的所有主鍵,然後再對它們調用.Load()。 有沒有人有這個解決方案?好像EF7,或Core 1.0解決了這個:
- 徹底消除延遲加載,我們可以關掉爲好,但它會破壞很多舊的代碼。
- 添加新的「ThenInclude」功能,據稱提高鏈接的效率大量包括。
如果關閉延遲加載是答案,那很好,我只是想在耗費大量時間重新開發一個巨大的webapps價值的服務調用之前耗盡所有選項。 有沒有人有任何想法?我願意投入一切。我們正在使用EF6。
編輯:它似乎答案是關閉延遲加載在上下文級別,或升級到EF7。如果其他人設法找到一種解決方案,我可以改變這種情況,您可以通過強制加載EF6單個對象進行代理跟蹤。
您是否運行SQL事件探查器來查看實際的SQL查詢是什麼? – Ellesedil
是的,我可以告訴你,從字面上看,無論何時您鏈接到第三級,查詢都會非常低效。這是因爲這些查詢是程序化生成的,所以這是可以理解的。可以理解,它不適用於專業級軟件。 一個解決方案是腳趾保存.Load()的結果並手動將其設置爲正確的對象。所以在這種情況下,加載所有的C並將它們設置爲B,但是這裏的所有開發人員都同意,我們不喜歡這樣。 我們喜歡當虛擬被移除時的功能,但我們也希望代理跟蹤,因此我們可以添加到對象B中的icollection。 – Gaugeforever
據我所知,您可以添加第三點到EF 7的優勢。它最終實現了批量查詢,這意味着它可以將單個調用中的許多查詢捆綁到SQL中。這應該允許它對依賴實體發出不同的查詢,同時還會導致對SQL的單個調用,而不是之前發出的可怕單個查詢。對於延遲加載的性能問題,由於缺少批量延遲加載功能,這是EF特定的問題。請參閱[這裏用NHibernate的解釋](/ a/36070727/1178314)。你的情況將會改變遊戲規則。 –