EFCore中的約定簡單來說就是規則,CodeFirst基於模型的約定來映射表結構。除此之外還有Fluent API、Data Annotations(數據註釋) 可以幫助我們進一步配置模型。 按照這三者的優先順序高低排序分別是:Fluent API、Data Annotations(數據註釋)、約定 ...
EFCore中的約定簡單來說就是規則,CodeFirst基於模型的約定來映射表結構。除此之外還有Fluent API、Data Annotations(數據註釋) 可以幫助我們進一步配置模型。
按照這三者的優先順序高低排序分別是:Fluent API、Data Annotations(數據註釋)、約定。
1.約定
public class Person { public int ID { get; set; } public int Age { get; set; } public bool Status { get; set; } public string Name { get; set; } public DateTime CreateTime { get; set; } }
1.1 主鍵約定
我們有這樣的一個Person類,在實體中如果有名為ID的欄位,或者實體名+ID的欄位如:PersonID,那麼EFCore生成的表會自動標識為主鍵。並且如果它的類型是int或Guid則會預設自增長。
映射之後的表結構:
我們可以看到C#中的int、bool、string、datetime,分別映射為 int,bit,navarchar(MAX),datetime2(7)。這是因為EFCore的預設約定是這麼規定的。道友們可能會想自定義的映射,比如把string映射會varcher,datetime映射為datetime。嗯。。這就需要藉助Fluent API或Data Annotations了。
1.2 外鍵約定
新建一個訂單類,並添加Person類型的欄位,以及PersonID(以類名+ID的形式),併在上下文中註冊。EFCore在映射表時會根據我們給定Person類型和PersonID來添加外鍵約束。
public class Order { public Guid ID { get; set; } public int PersonID { get; set; } public Person Person { get; set; } public string Address { get; set; } public string Phone { get; set; } }
修改Progarm.cs代碼
class Program { static void Main(string[] args) { var context = new CoreDbContext(); // 刪除資料庫 context.Database.EnsureDeleted(); // 告訴EFCore我們要創建資料庫 context.Database.EnsureCreated(); // 初始化數據 var person = new Person() { Name = "季某人", Age = 11, Status = true, CreateTime = DateTime.Now, }; var person2 = new Person() { Name = "季某人", Age = 11, Status = true, CreateTime = DateTime.Now, }; var order = new Order() { PersonID = 1, Address = "地球XX", Phone = "00000" }; context.Person.Add(person); context.Person.Add(person2); // 這裡因為添加了外鍵,所以要先保存Person,不然會報外鍵的錯誤 context.SaveChanges(); context.Order.Add(order); context.SaveChanges(); //Console.WriteLine("Hello World!"); } }
啟動項目,然後查看資料庫。
可以看到數據完成了初始化,並且添加了外鍵約束。
2.Data Annotations(數據註釋)
數據註釋就是在屬性上添加一些特性標簽,告訴EFCore我們要映射的類型是什麼樣的,當預設的映射不能滿足我們的需求時,就可以使用數據註釋了。例如前面的映射,string類型映射為資料庫的nvarchar(max),DateTime映射為datetime2(7)。 使用數據註釋可以改變為我們想要映射成的類型,例如:string映射成varvhar。
添加一個新類OrderDetail,並添加數據註釋。
public class OrderDetail { [Key] // 標識主鍵 public int ID { get; set; } [Column(TypeName = "varchar(50)")] // 列的數據類型 [Required] // 必填列 public string Price { get; set; } public DateTime? CreateTime { get; set; } [Column("OrderCode")] // 列的顯示名字 [StringLength(50)] // 列的長度 public string Code { get; set; } public Guid? OrderID { get; set; } public Order Order { get; set; } }
啟動項目,觀察映射成的表結構。與實體中的配置一樣。
基本常用的就這些,其他的用到的時候可以去官網文檔上找。
3.Fluent API
Fluent API 相較於 數據註釋更加靈活。它的配置需要寫在自定義的上下文類中的OnModelCreating方法中。
比如改變表名,數據類型之類的
效果和數據註釋是一樣的,值得註意的是當Fluent API 和數據註釋同時配置一個屬性時,Fluent API會覆蓋掉數據註釋。
除了上述之外還可以利用Fluent API 統一表的命名規範:例如 "T_+實體名".
protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var item in modelBuilder.Model.GetEntityTypes()) { modelBuilder.Entity(item.Name).ToTable("T_" + item.ClrType.Name); } }
遍歷要映射的實體然後加上 "T_" 首碼。
具體差異可以觀看微軟EFCore文檔,傳送門:https://docs.microsoft.com/zh-cn/ef/core/modeling/relational/data-types