默認情況下,EF Core有一個「代碼優先思路」,即它應該以代碼優先的方式使用,即使支持數據庫優先方法,它也被描述爲對現有方法進行反向工程數據庫並創建它的代碼優先表示。我的意思是,在代碼中「手工」(代碼優先)創建並從數據庫(通過Scaffold-DbContext命令)生成的模型(POCO類)應該是相同的。在Entity Framework Core中編寫實體POCO類的正確方法是什麼?
令人驚訝的是,官方EF核心文件證明了顯着的差異。下面是在代碼中創建的模型的例子:從現有的數據庫https://ef.readthedocs.io/en/latest/platforms/aspnetcore/new-db.html這裏是的例子逆向工程是:https://ef.readthedocs.io/en/latest/platforms/aspnetcore/existing-db.html
這是在第一種情況下的實體類:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
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; }
}
,這是第二種情況下的實體類:
public partial class Blog
{
public Blog()
{
Post = new HashSet<Post>();
}
public int BlogId { get; set; }
public string Url { get; set; }
public virtual ICollection<Post> Post { get; set; }
}
第一個例子是一個非常簡單,非常明顯的POCO類。它在文檔中隨處可見(數據庫生成的示例除外)。第二個例子,雖然,有一些補充:
- 類被聲明爲部分(即使有無處可看它的另一個部分定義)。
- 導航屬性的類型爲ICollection < T>,而不僅僅是列表< T>。
- 導航屬性初始化爲新的HashSet < T>()在構造函數中。代碼優先例子中沒有這樣的初始化。
- 導航屬性被聲明爲虛擬。
- 生成的上下文類中的DbSet成員也是虛擬。
我已經試過從數據庫(本文寫作時最新的工具)腳手架模型,它生成的實體完全如圖所示,所以這不是一個過時的文檔問題。所以官方的工具生成不同的代碼,官方文檔建議編寫不同的(不重要的)代碼 - 沒有部分類,虛擬成員,構造初始化等。
我的問題是,試圖在代碼中構建模型,應該如何我寫我的代碼?我喜歡使用ICollection而不是List,因爲它更通用,但除此之外,我不確定是否需要關注文檔或MS工具?我需要將它們聲明爲虛擬嗎?我需要在構造函數中初始化它們嗎?等等......
我從舊時代EF知道,虛擬導航屬性允許延遲加載,但它不支持連(尚)在EF核心,我不知道任何其他用途。也許它會影響性能?也許工具嘗試生成面向未來的代碼,這樣,當延遲加載將被執行,在POCO類和上下文就能支持呢?如果是這樣,我能夠擺脫他們,因爲我並不需要懶加載(所有數據查詢是在回購封裝的)?
不久,請幫助我瞭解爲什麼差別,以及風格應該在代碼構建模型時怎麼用?
關於第3點,根據我自己最近項目的經驗...我強烈建議不要初始化它們以清空構造函數中的集合。原因在於,在許多情況下,您的業務邏輯需要能夠確定明細集合是空的還是尚未加載。 –