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
原文出處:https://www.cnblogs.com/jixiaosa/p/10328377.html