導航屬性應該是虛擬的 - 在ef核心中不需要?

c# entity-framework entity-framework-core navigation-properties 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; }
    }

它不再需要了嗎?

一般承認的答案

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

由於EF Core尚不支持延遲加載 ,因此當前virtual沒有特殊含義。它會(以及如果)他們添加延遲加載支持(有一個這樣做的計劃 )。

更新:從EF Core 2.1開始,現在支持延遲加載 。但是,只要您不添加Microsoft.EntityFrameworkCore.Proxies包並通過UseLazyLoadingProxies啟用它,原始答案仍然適用。

但是,如果這樣做,由於初始實現中缺少選擇加入控制,事情會完全改變 - 它要求 所有導航屬性都是virtual 。這對我來說沒有意義,你最好不要使用它,直到它得到修復。如果你確實需要延遲加載,請使用替代的Lazy加載而不使用代理方法,在這種情況下, virtual無關緊要。


熱門答案

自從接受了答案後,情況發生了變化。在2018年,對於兩種不同的方法, 現在支持實體框架核心2.1的延遲加載

兩者的簡單方法是使用代理,這將需要延遲加載的屬性用virtual定義。要從鏈接頁面引用:

使用延遲加載的最簡單方法是安裝Microsoft.EntityFrameworkCore.Proxies包並通過調用UseLazyLoadingProxies啟用它。 [...]然後,EF Core將為任何可以覆蓋的導航屬性啟用延遲加載 - 也就是說,它必須是虛擬的,並且可以繼承自可繼承的類。

以下是提供的示例代碼:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public virtual Blog Blog { get; set; }
}

還有另一種不使用代理進行延遲加載的方法, ILazyLoader注入數據類型的構造函數。 這在這裡解釋

簡而言之,有兩種方法可以執行延遲加載:使用和不使用代理。當且僅當您希望支持使用代理進行延遲加載時,才需要 virtual 。否則,事實並非如此。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因