推薦關注「碼俠江湖」加星標,時刻不忘江湖事
這是 EF Core 系列的第二篇文章,上一篇文章講解了 EF Core 的一些基礎概念,這一篇文章主要圍繞實體屬性的配置。
點擊上方或后方藍字,閱讀 EF Core 系列合集。
實體配置
配置實體的目的,是為了讓實體屬性與數據庫表字段實現正確的映射。
EF Core 有三種方式來配置實體:按約定、數據注釋、Fluent API,下面依次進行闡述。
按約定配置
按約定配置,是指 EF Core 遵循一套關于屬性類型和名稱的簡單規則,并相應地配置數據庫。
按約定的配置,可以被數據注釋(特性)或 Fluent API 重寫。
比如,下面這個示例中:
public?class?Account
{public?Guid?AccountId?{?get;?set;?}public?string?Name?{?get;?set;?}public?int?Age?{?get;?set;?}
}
EF Core 通過遵循命名規則,來配置 Account
實體類中的主鍵字段。
如果實體類擁有一個名為 Id
的屬性,或一個<類名+Id>
的組合,它就會被作為主鍵。
如果實體類中有一個復合主鍵,我們就不能按約定配置了。
當 EF Core 使用按約定的配置時,它會遍歷所有的公共屬性,并通過它們的名稱和類型來映射它們。
示例中,Name
屬性是一個可以為 Null
的字段,因為字符串類型的默認值是 Null
。
但 Age
屬性不會為 Null
,因為它是一個值類型。
當然,如果你想讓 Age
屬性,在數據庫中可以為 Null
,那需要在類型后加上 「?」 后綴:
public?int??Age?{?get;?set;?}
數據注釋
數據注釋的表現形式就是特性,它不僅可以用來配置實體屬性,還可以永遠驗證實體數據是否合法。
我們來替換一下 Account
實體類中的內容:
using?System;
using?System.ComponentModel.DataAnnotations;
using?System.ComponentModel.DataAnnotations.Schema;namespace?ConsoleApp1.Entities
{[Table("Account")]public?class?Account{[Column("AccountId")]public?Guid?Id?{?get;?set;?}[Required][MaxLength(50,?ErrorMessage?=?"長度必須小于50個字符")]public?string?Name?{?get;?set;?}public?int?Age?{?get;?set;?}}
}
Name
屬性的特性,它就是數據注釋的一種,來自 System.ComponentModel.DataAnnotations
命名空間,這個命名空間中的屬性主要與約束有關。
Required
屬性,說明 Name
字段不能為空;MaxLengh
屬性,限制了數據庫中該列的長度。
Account
類型與 AccountId
屬性的特性,也屬于數據注釋。
不過,它們來自于 System.ComponentModel.DataAnnotations.Schema
命名空間,這個命名空間中的屬性主要與數據庫配置有關。
默認情況下,實體類映射到數據庫中的表名,與上下文類中 DbSet 屬性名有關。
比如 DbSet<Account>
,它的屬性名是 Accounts,
所以映射到數據庫中的表名就是 Accounts
。但是使用了 「Table」 特性就會覆蓋這個默認行為。
「Column」 特性,則可以為 EF Core 提供,該屬性映射到數據庫中的列信息。
如果你想在代碼中使用 Account
類的 Id
屬性,而不是 AccountId
,而又想讓它在數據庫中,以 AccountId
字段名表示,那么就需要使用 「Column」 特性。
「Column」 特性中還有其它的一些參數,比如字段的順序與數據庫中的類型等,簡單來說,它可以定義屬性在數據庫中的形式。
Fluent API
Fluent API 是一組方法,這些方法提供了大量的 EF Core 配置選項,用來在上下文類中配置實體。
我們可以在 ApplicationContext
類中,添加這么一段代碼:
protected?override?void?OnModelCreating(ModelBuilder?modelBuilder)
{modelBuilder.Entity<Account>().ToTable("Account");modelBuilder.Entity<Account>().Property(s?=>?s.Id).HasColumnName("AccountId");modelBuilder.Entity<Account>().Property(s?=>?s.Name).IsRequired().HasMaxLength(50);modelBuilder.Entity<Account>().Property(s?=>?s.Age).IsRequired(false);
}
Fluent API 可以在 OnModelCreating
方法中使用,這段配置與前面的數據注釋擁有同樣的效果。
Fluent API 的使用,需要在一開始,就選擇需要配置的實體,然后通過 Property
方法,指定需要添加約束的屬性,其他的方法就很清晰明了了。
OnModelCreating
方法會在 ApplicationContext
類第一次實例化時被調用。也就是在這一刻,所有的三種實體配置方式都會被應用。
由于配置規則非常多,而常用的又并不多,所以更多的配置規則,大家可以通過 EF Core 官方文檔去查閱。
配置方式的選擇
現在,我們主要來說一說,這三種配置方式, 我們應該怎么選擇?
「首先是按約定配置,」這個永遠都是我們的首選。
因為,擁有與表名相同的類名、擁有與命名約定相匹配的主鍵屬性名,以及擁有與列相同的名稱和類型的屬性,是我們的首選。這樣不需要我們做太多的工作。
「然后是數據注釋」,它不僅可以配置實體,最重要的是可以實現數據驗證,如必填或最大長度驗證等,我們應該使用數據注釋,而不是 Fluent API 方法。
原因在于,我們可以很容易的看到,哪個驗證規則與哪個屬性有關,因為它就在屬性的上方,而且具有語義性。另外,數據注釋的驗證,還可以應用在 MVC 中的視圖頁面。
比如在 Account
類中,如果驗證失敗,還可以配置錯誤信息。這種方法會讓我們的驗證代碼更簡單,更容易維護。
「最后是 Fluent API」 ,它用于以上兩種方法以外的情況,比如索引、復合鍵、關系都應該使用 Fluent API。
對于那些我們無法做到的配置,或者當我們想從實體類中隱藏配置時,也必須使用這種方法。
小結
這篇文章主要講了實體屬性的三種配置方式,下篇文章我們將圍繞實體的數據庫遷移與種子數據的填充。
更多精彩內容,請關注我▼▼
如果喜歡我的文章,那么
在看和轉發是對我最大的支持!
(戳下面藍字閱讀)
ASP.NET 6 中間件系列
查缺補漏系統學習 EF Core 6? 系列
推薦關注微信公眾號:碼俠江湖
? ? ? ? ? ? ? ? ? ? ? ??覺得不錯,點個在看再走喲