經過ToTable能夠爲數據模型在數據庫中自定義表名,若是不配置,則表名爲模型名的複數形式數據庫
public class EmployeeConfig:IEntityTypeConfiguration<Employee> { public void Configure(EntityTypeBuilder<Employee> builder) { // 默認狀況下,Employee實體在數據庫中會生成Employees的數據表,這裏經過ToTable(),將其指定爲Employee builder.ToTable("Employee"); } }
在EF Core中,經過Fluent API作表間關係映射時,能夠將API分爲兩類兩種api
兩類:has和withui
三種:One、Manycode
經過兩類兩種的組合,就能夠完成絕大多數表間關係的映射,下面放一些經常使用的關係配置對象
public class EmployeeConfig:IEntityTypeConfiguration<Employee> { public void Configure(EntityTypeBuilder<Employee> builder) { builder.ToTable(nameof(Employee)); // 配置Employee表有一個Department對象,Department有多個Employee對象 // 這是典型的一對多配置 builder.HasOne(e => e.Department).WithMany(d=>d.Employees); } }
一般配置一對多的時候只須要在一張表上進行配置就能夠了,但也能夠在兩張表上都進行配置,這樣更清晰ci
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { builder.ToTable(nameof(Department)); // 配置Department表有多個Employee對象,Employee有一個Department對象 builder.HasMany(d => d.Employees).WithOne(e=>e.Department); // 配置Department表有一個領導(也是Employee對象),領導也屬於一個部門 builder.HasOne(d => d.Leader).WithOne(e => e.Department); } }
在表關係的配置中,遵循 Has…( ).With…( )的配置方式,Has指的是配置的這張表,而後經過lambda表達式來指定對應的屬性,如上面的Department表,經過lambda表達式 d => d.Employees 指定要配置的字段是Employess,HasMany則是指Department表的Employees對應多個文檔
With則是前面has指定的屬性對應的表,WithOne反過來指定了Employee表中的Department字段是一個字符串
因此這裏就是一個多對一的配置get
經過這四個單詞的組合,就能夠完成一對多、一對1、多對多(經過中間表拆分紅兩個一對多)的表間關係配置string
這裏將Entity文件放出來,以便更好理解
public class Employee { public Guid Id { get; set; } public string Name { get; set; } public bool Gender { get; set; } public string Phone { get; set; } public decimal Rating { get; set; } public decimal Salary { get; set; } public Guid DepartmentId { get; set; } public Department Department { get; set; } } public class Department { public Guid Id { get; set; } public string Name { get; set; } public Guid LeaderId { get; set; } public Employee Leader { get; set; } public List<Employee> Employees { get; set; } public string NoUse { get; set; } }
EF Core會自動將實體中名爲Id的屬性設置爲主鍵,可是有時候主鍵並非這麼規整的命名,或者須要聯合主鍵的狀況,就須要手動指定主鍵
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { // 配置數據庫中主鍵爲實體的Id字段 builder.HasKey(d => d.Id); } }
這裏指定了Department的Id字段爲主鍵,實體屬性名爲Id不用手動指定,這裏只是展現一下自定義的語法
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { // 配置數據庫中主鍵爲實體的Id和Name的聯合主鍵 builder.HasKey(d => new {d.Id, d.Name}); } }
聯合主鍵的設置也很簡單,經過new一個匿名對象的方式提供
EF Core會默認爲主鍵生成值,但有時候咱們但願使用主鍵而且本身自定義相關的值,好比說自選帳號、課程Id等,這時能夠這樣配置
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { builder.Property(d => d.Id) .ValueGeneratedNever(); // 配置數據庫中實體的Id字段不自動生成值 } }
經過ValueGeneratedNever()能夠禁用自動生成值,實際上它能夠給任何一個屬性都配置,可是一般只有主鍵是默認生成值的
若是有外鍵則必須有另外一個與之關聯的表,因此外鍵配置只能在表關係配置後附加
EF Core會默認將關聯表+Id的字段設置爲外鍵,同主鍵同樣,有時候不是那麼規整,就須要手動指定
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { builder.HasOne(d => d.Leader).WithOne(e => e.Department).HasForeignKey("LeaderId"); } }
在Department實體中指定了Leader,Leader也是Employee對象,若是依照約定屬性爲EmployeeId會自定設置爲外鍵字段,可是這裏指定了LeaderId,就須要手動設置外鍵字段爲LeaderId
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { // 數據庫中忽略該字段,該字段不會存在該實體屬性對應的字段 builder.Ignore(d => d.NoUse); } }
前面Department實體中有一個NoUse字段,可是不但願它在數據庫中映射該字段,就能夠經過Ignore的方式忽略掉
經過Fluent API可以對字段進行約束,這樣在生成數據庫表時就會將相應的約束生成,如設置了字段的最大長度在數據庫表中的字段數據類型時nvarchar(設定的最大長度),若是沒有設置,在數據庫表中的字段數據類型則是nvarchar(max)
Fluent支持流式語法,能夠將多個約定流式附加
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { // 設置姓名字段不爲空 builder.Property(d => d.Name).IsRequired(); } }
public class DepartmentConfig:IEntityTypeConfiguration<Department> { public void Configure(EntityTypeBuilder<Department> builder) { // 設置姓名字段最大長度爲30,且不爲空 builder.Property(d => d.Name).HasMaxLength(30).IsRequired(); } }
public class EmployeeConfig:IEntityTypeConfiguration<Employee> { public void Configure(EntityTypeBuilder<Employee> builder) { // Phone字段在數據庫中爲11位固定長度字符串 IsFixedLength()用於指定該字段是否爲固定長度 builder.Property(e => e.Phone).HasMaxLength(11).IsFixedLength(); } }
IsFixedLength()用於指定該字段是否爲固定長度,其長度爲前面設置的字段最大長度
public class EmployeeConfig:IEntityTypeConfiguration<Employee> { public void Configure(EntityTypeBuilder<Employee> builder) { // 顯式指定實體屬性對應數據庫中的字段名,這裏指定Phone字段對應的數據庫字段爲ChinaPhone builder.Property(e => e.Phone).HasColumnName("ChinaPhone"); } }
public class EmployeeConfig:IEntityTypeConfiguration<Employee> { public void Configure(EntityTypeBuilder<Employee> builder) { // 指定decimal的精度爲5刻度爲2 builder.Property(e => e.Rating).HasColumnType("decimal(5, 2)"); } }
注:關於精度和刻度的解釋,精度是數字的位數,刻度是小數的位數,即decimal(5, 2)能表示的最大數是999.99,一共五位,小數兩位
指定數據類型更經常使用的狀況是將實體的decimal類型指定爲數據庫中的money類型
public class EmployeeConfig:IEntityTypeConfiguration<Employee> { public void Configure(EntityTypeBuilder<Employee> builder) { // 指定decimal的精度爲5刻度爲2 builder.Property(e => e.Salary).HasColumnType("money"); } }
由於進行了分組配置,將每一個類的配置分別拆分到不一樣的文件
具體的配置能夠看看微軟的官方文檔