2013-03-21 52 views
12

我正在使用EF(dll版本爲4.4)來針對數據庫進行查詢。該數據庫包含幾個包含課程信息的表格。當看看實際發送給db的數據時,我看到一條巨大的,近1300行的SQL查詢(由於它的大小,我不打算在這裏粘貼)。我在上下文中運行的查詢是這樣的:如何避免EF中使用Include時生成的大量SQL查詢()

entities.Plans 
    .Include("program") 
    .Include("program.offers") 
    .Include("program.fees") 
    .Include("program.intakes") 
    .Include("program.requirements") 
    .Include("program.codes") 
    .Include("focuses") 
    .Include("codes") 
    .Include("exceptions") 
    .Include("requirements") 
where plans.Code == planCode 
select plans).SingleOrDefault(); 

我想避免從每個相關表的收集信息時,返回到服務器,但如此龐大的查詢我想知道如果有沒有更好的方法來做到這一點?

謝謝。

+0

那麼你正在做急於加載,你的查詢試圖一次獲得所有的數據,因此它爲什麼很大。你在那裏看到什麼問題?其他選項是使用虛擬屬性進行延遲加載,當您試圖訪問它們時,EF將在後臺獲取該屬性,但您確實指定了不希望往返於數據庫。 – 2013-03-21 06:36:08

+0

這裏有一種類似的答案http://stackoverflow.com/questions/5521749/how-many-include-i-can-use-on-objectset-in-entityframework-to-retain-performance – 2013-03-21 06:37:39

+0

我想我是想知道我是否正確地看着這個。一個龐大的查詢與幾個小的查詢或是否有更好的方法來做到這一點。 – b3n 2013-03-21 08:16:20

回答

0

您通常可以在where子句後面添加.Include()。這意味着您只需提取符合您需要的信息,查看是否可以減少您的查詢。

+1

這沒有什麼區別。我在LINQPad中運行查詢,並且在兩種情況下生成的SQL都是相同的。 – b3n 2013-04-29 02:28:37

+0

'在where子句後面,它仍然是一樣的?似乎有點奇怪......我建議的其他事情是嘗試導航屬性,我相信它們的工作方式稍有不同,但我實際上並不完全理解它們。 或者,您可以使用filter/where子句從計劃表中提取信息。然後運行一些加入語句來獲得你所需要的。代碼不是很簡潔,但它應該能夠加快速度。 – Trent 2013-04-29 04:30:34

0

由於您正在執行熱切加載,所以如果您選擇所需的實體,那麼它很好。否則,您可以使用Lazy Loading,但如您所指定的,您不希望數據庫往返,因此您可以避免它。

我會建議,如果這個查詢被多次使用,那麼你可以使用編譯查詢。這樣會提高性能。

通過這個鏈接,如果你想.. http://msdn.microsoft.com/en-us/library/bb896297.aspx

0

如果您使用DbContext,您可以使用.Local屬性上下文看,如果你的實體已經獲取的,因此附加到上下文。

如果查詢已運行之前,你的根Plan實體已經連接基於Plan.Code == planId,想必它的子實體也已經連接,因爲你沒有預先加載,通過導航屬性將不會打這麼提到他們DB在他們的生命週期中再次使用它們。

This article可能有助於使用.Local

0

可能能夠通過使用投影而非Include拉回到你提到的實體獲得稍微更簡潔的SQL查詢:如果你對你的背景下這種禁用延遲加載

var planAggregate = 
(from plan in entities.Plans 
    let program = plan.Program 
    let offers = program.Offers 
    let fees = program.Fees 
    //... 
    where plan.Code == planCode 
    select new { 
    plan 
    program, 
    offers, 
    fees, 
    //... 
    }) 
    .SingleOrDefault(); 

的查詢將導致實體的導航屬性被包含在查詢中的實體填充。我只在EF.dll v5.0上測試過它,但它在EF.dll v4.4上的表現應該是一樣的,它只是在.NET 4.0上的EF5。當我測試使用這個模式而不是Include在類似形狀的查詢中,它會從500行SQL中刪除大約70行,您的里程可能會有所不同。)

1

有點遲了,但是,由於您的數據每天只會更改一次,請考慮將所需的一切索引視圖並將此視圖放置在您的EF模型中。

相關問題