8

我記得在EF navigation property should be virtual導航屬性應該是虛擬的 - 在ef核心中不需要?

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; } 
} 

但我看EF Core並沒有看到它作爲虛擬:

public class Student 
    { 
     public int ID { get; set; } 
     public string LastName { get; set; } 
     public string FirstMidName { get; set; } 
     public DateTime EnrollmentDate { get; set; } 

     public ICollection<Enrollment> Enrollments { get; set; } 
    } 

難道不是必需的了嗎?

回答

20

virtual從未需要。只有在需要延遲加載支持時才需要它。

由於Lazy loading is not yet supported by EF Core,目前virtual沒有特別的意義。它會在什麼時候(以及如果)添加延遲加載支持(這樣做有一個plan)。

+0

如果它沒有特殊含義,爲什麼腳手架用虛擬生成每個導航屬性? –

+0

@CamiloTerevinto以防萬一?默認?現在真的沒關係。 –

+0

很有趣,其實我想知道他們是EF默認虛擬內核,我不這麼認爲 –

3

在EF Core中默認選擇了阻止延遲加載的路徑。 另外我覺得這個功能在這個問題之後還沒有實現。

https://github.com/aspnet/EntityFramework/issues/3312

與以前版本的EF的允許延遲加載相關實體的虛擬導航性能。

我想現在裝導航性能只能與.Include(...)

編輯被achived:

有其在覈心支持加載相關實體的幾種方法。 如果你有興趣:在EF https://docs.microsoft.com/en-us/ef/core/querying/related-data

8

它從未被要求...

由於其他的答案在這裏,我看到EF核心竟然不支持延遲加載......它使虛擬鍵字漂亮......核心無用

,但一般:

1.如果你申報你的財產的虛擬:

你的虛擬財產(默認情況下)不會馬上查詢的主要對象時加載。只有嘗試訪問數據庫或訪問其中的某個組件時,它纔會從數據庫中進行檢索。

這就是所謂的延遲加載。

2.如果你聲明它非虛:

你的財產將(默認),可以用在您的主實體上所有的其他財產一起馬上加載。這意味着您的財產將準備好訪問:它已被撤回。因爲您訪問此屬性,實體將不必再次查詢數據庫。

這被稱爲熱切加載。

我的看法:

更多的時候我選擇熱切加載(非虛擬的),因爲大部分的時間,我需要每一個實體的每一個屬性,而不必查詢返回(在快一起使用如果你只是偶爾訪問這個屬性(你沒有列出任何東西),而且你希望更多的時候只是其餘的信息不用這個,那麼就讓它變成虛擬的,這樣這個屬性不會變慢查詢的其餘部分僅用於一些訪問。

希望這是明確的......

Exemples:

如果我不會用虛擬(急切地):

foreach(var line in query) 
{ 
    var v = line.NotVirtual; // I access the property for every line 
} 

在那裏我會使用虛擬或延遲加載:

foreach(var line in query) 
{ 
    if(line.ID == 509)  // because of this condition 
    var v = line.Virtual; // I access the property only once in a while 
} 

最後一件事:

如果您沒有查詢1000行以上的數據庫,那麼無論您選擇什麼都不會有很大的影響。此外,您可以聲明這些屬性是虛擬的,如果您想以相反方式測試,您只需執行以下操作:

context.LazyLoadingEnabled = false; 

它將取消虛擬效果。

編輯

對於EF的新版本:

WhateverEntities db = new WhateverEntities() 
db.Configuration.LazyLoadingEnabled = false;