筆記一下 EF Core 消極載入的前世今生
先下結論
- EF Core (.Net Core)
預設是積極載入,不需要再加 virtaul
如果特別設定成消極載入,則一樣要補上 virtaul - EF (.Net Framework)
預設是消極載入,要啟用需要加 virtaul
但也可以不加,就不走消極載入
遙想當年還沒開始用EF時,問我友人巡覽屬性的事情,他要我不要用
後來查了一下其實是消極載入如果使用不當會造成N+1的查詢效能問題
最後還是用了 virtual 來宣告巡覽屬性,想說注意一下就好了
後來轉到 Dotnet Core 還是習慣把實體的巡覽屬性當加上 virtual
有看到一些程式或文章沒有加也沒特別注意這事情 (沒特別注意是 EF or EFCore)
今天心血來潮查了一下資料才了解了事情原委
就以前 EF 預設是消極載入,需要用 virtual 宣告巡覽屬性
後來到了 EF Core 預設是積極載入,不需要 virtual
並且初期也不支援消極載入,畢竟草創時期缺一堆API
現在 EF Core 也有開始支援延遲載入了
但是需要另外設定 Proxy (不是加了 virtual 就可以完事)
不過官方也警告延遲載入用不好會造成 N+1 效能問題
https://docs.microsoft.com/zh-tw/ef/core/querying/related-data/lazy#lazy-loading-with-proxies
警告
消極式載入可能會導致不必要的額外資料庫往返發生 (所謂的 N + 1 問題) ,而且應該小心避免此情況。 如需詳細資訊,請參閱 [效能] 區段 。
建議沒特別要求就盡可能使用預設的積極載入就好
至於何時需要用到消極載入
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; } = new List<Post>();
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
如果想一條 linq 取得100個Blog.Url
換其中一個 Blog.Post
如果直接積極載入 include 全部 Post 就會撈出 100篇部落格文章
但其實只會用到其中一篇
這時候就不適合積極載入
反而比較需要消極載入
或是就不 include
直接分兩個 linq 來查詢
這篇主要不是講這個就這樣帶過
有需要可以自行詢問古哥哥