2017-01-10 52 views
2

我有一個MVC項目,我用EF來從Northwind數據庫中導入Products和Categories表。 Products表對CategoryID表的CategoryID字段具有CategoryID上的外鍵約束。我使用該向導使用EF添加了包含視圖的MVC 5控制器。 Index操作方法的代碼MVC自動生成索引方法 - 爲什麼需要.include?

// GET: Products 
    public ActionResult Index() 
    { 
     var products = db.Products.Include(p => p.Category); 
     return View(products.ToList()); 
    } 

我認爲在.include在那裏的範疇帶來,並允許在視圖中顯示的類別名稱。但後來我查看了Details操作方法,即使它顯示了類別名稱,它也不使用此代碼。所以然後我試圖剝離索引方法的.include來獲得這個

var products = db.Products; 

並運行它,我仍然得到在視圖中顯示的類別名稱。所以現在我很困惑,爲什麼.include代碼在Index操作方法中,而不是在Details方法中。任何輸入讚賞。

感謝

+0

如果您事先知道需要'Category',那麼最好是'Include()',這樣EF就會生成一個更高效的SQL來檢索它。當您不使用Include()時,EF將以「延遲加載」模式運行,並在嘗試訪問「Category」時發出另一個SQL。顯然,只有在配置中啓用延遲加載(默認情況下),延遲加載纔會起作用。 – haim770

回答

5

Include對底層的SQL查詢的影響。使用該查詢時,查詢將在類別表上進行連接,否則,查詢將僅加載產品表中的數據。如果啓用延遲加載(默認情況下),則在訪問屬性時將從數據庫加載類別。

從應用程序,這意味着你會得到完全相同的結果。與Include不同的是,只有一個查詢會被創建,如果沒有它,您將有一個查詢來檢索產品列表,然後每次需要首次訪問產品的類別時再進行一次查詢。性能影響可能很大(這被稱爲N + 1問題,因爲要加載N個項目的列表,您必須對數據庫執行N + 1次往返)。

+0

對於急切的查詢,您可以使用'objectContext.LazyLoadingEnabled = false;' –

+0

設置延遲加載謝謝,這會清理一些東西。但我仍然不確定爲什麼.include不在Details方法中。 Details和Index視圖都需要顯示CategoryName。這只是一種怪癖,它是在一種方法而不是另一種方法,還是我仍然錯過了一些東西? – BrainPain

+0

我想這僅僅是因爲在Details方法中,你可能只加載了1個對象,這意味着延遲加載對性能的影響要比在索引上的影響小得多,在那裏加載可能有數百個對象。對我來說,看起來代碼首先沒有任何'Include'編寫,後來在優化時,它被添加到性能影響最大的地方。 – Riokmij

相關問題