2011-04-08 76 views
198

當在EF Code First?中使用屬性時,virtual關鍵字是否有效?有人能夠在不同情況下描述其所有後果嗎?例如,我知道它可以控制lazy loading - 如果在ICollection/one-to-many關係屬性中使用virtual關鍵字,則默認情況下它將被延遲加載,而如果將virtual關鍵字保留,它會被急切加載。虛擬關鍵字在Entity Framework 4.1 POCO Code First中有什麼作用?

virtual關鍵字可以在EF中使用POCO實體嗎?我是否應該默認在我的所有屬性上使用virtual,或者默認不使用它?

回答

172

到目前爲止,我知道這些影響。

  • Lazy Loading:任何virtual ICollections將延遲加載,除非您特別紀念他們,否則。
  • More efficient change tracking。如果您滿足以下所有要求,那麼您的更改跟蹤可以通過掛鉤您的虛擬屬性來使用更高效的方法。從鏈接:

    要得到改變跟蹤代理的 基本規則是,你的類必須是公共 ,非抽象的或者非密封。 你的課程還必須爲所有持有的 屬性實施公開的 虛擬獲取者/設置者。 最後,您必須僅聲明基於集合 的關係導航 屬性爲ICollection<T>。 它們不能是一個具體的實施 或從ICollection<T>派生(一 差從延遲加載 代理),另一個接口

描述這是MSDN的Requirements for Creating POCO Proxies另一個有用的鏈接。

+49

沒有其他原因,使性能虛擬。導航屬性在延遲加載時標記爲虛擬,標量屬性標記爲虛擬以進行更改跟蹤。 – 2011-04-08 18:31:25

+6

什麼是導航屬性和什麼是標量屬性? – 2012-07-10 10:30:36

+7

@AbidAli:我相信導航屬性是一個外鍵(一個實體類類型)或一對多關係(ICollection <>類型)。標量屬性是基本類型(int,string,..)或ComplexType(它只是基本類型的結構)。 – 2012-07-18 14:30:54

46

該虛擬關鍵字與從實體框架(延遲加載,急切加載和顯式加載)加載數據的主題相關。

您應該使用虛擬關鍵字,當你想用延遲加載加載數據。

遲緩裝載是過程,由此實體的實體或集合從所述數據庫中的第一時間被訪問自動加載。

例如,使用下面定義的博客實體類時,相關的帖子將被加載在第一時間的帖子導航屬性被訪問:

public class Blog 
{ 
    public int BlogId { get; set; } 
    public string Name { get; set; } 
    public string Url { get; set; } 
    public string Tags { get; set; } 
    public virtual ICollection<Post> Posts { get; set; } 
} 

的帖子集合的延遲加載可以通過關閉使Posts屬性非虛擬。

如果延遲加載關閉,則可以使用預先加載(使用Include方法)或顯式加載相關實體(使用Load方法)來加載Posts集合。

熱切加載:

using (var context = new BloggingContext()) 
{ 
    // Load all blogs and related posts 
    var blogs1 = context.Blogs 
          .Include(b => b.Posts) 
          .ToList(); 
} 

明確裝入:

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts related to a given blog 
    context.Entry(blog).Collection(p => p.Posts).Load(); 
} 
+1

如何避免使用虛擬(延遲加載)時出現N + 1問題?例如,context.Blogs.ToList();那麼它將不會加入表格,並且它會像選擇多個博客一樣運行選擇查詢。 – 2016-06-30 10:06:59

相關問題