Code First使你能夠通過C# 或者 Visual Basic .NET來描述模型,模型的基本規則通過使用約定來進行檢查,而約定就是一系列內置的規則。
在Code First中基於類的定義通過一系列的規則約定自動配置概念模型,約定被定義在命名空間System.Data.Entity.ModelConfiguration.Conventions中。
你可以進一步配置你的模型通過數據注解或者fluent API。
優先通過 fluent API配置緊隨其后的是數據注解約定。更多信息可以查看Data Annotations, Fluent API - Relationships, Fluent API - Types & Properties and Fluent API with VB.NET.
關於Code First的一系列約定可以參考API Documentation.這篇文章的主題主要闡述了Code First的約定。
類型探索
當我們使用Code First開發的時候,通過寫.NET Framework類來定義概念(領域)模型,除了定義類之外,你還需要讓DbContext知道哪些類型是你想要代表的模型。因此,你需要定義一個上下文類繼承自DbContext,用DbSet修飾你需要表示為模型的類型。Code First將包含這些類型並獲取這個引用類型,即使引用來下被定義在不同的程序集當中。
如果你的類在繼承結構體系當中,這些類在同一個程序集下面時,你將基類定義成一個DbSet屬性就足夠了,它將自動推斷出所包含的其它相關聯的類型。
public class SchoolEntities : DbContext { public DbSet<Department> Departments { get; set; } } public class Department { // Primary key public int DepartmentID { get; set; } public string Name { get; set; } // Navigation property public virtual ICollection<Course> Courses { get; set; } } public class Course { // Primary key public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } // Foreign key public int DepartmentID { get; set; } // Navigation properties public virtual Department Department { get; set; } } public partial class OnlineCourse : Course { public string URL { get; set; } } public partial class OnsiteCourse : Course { public string Location { get; set; } public string Days { get; set; } public System.DateTime Time { get; set; } }
如果你不想讓某一個類型作為模型類,你可以使用 NotMapped 屬性或者使用 fluent API的DbModelBuilder.Ignore.
modelBuilder.Ignore<Department>();
主鍵約定
如果在類中存在名為"ID"(不區分大小寫)的屬性或者是類名+"ID",Code First將自動推斷這個屬性作為主鍵。
public class Department { // Primary key public int DepartmentID { get; set; } . . . }
關系約定
在 Entity Framework中,導航屬性提供兩個實體類型之間的跳轉,導航屬性允許你從兩個方向導航和管理關系,它返回一個引用對象(1個或者0個)或者一個集合(多個對象列表)。Code First 是基於導航屬性來推斷類型直接的關系的。
除了導航屬性之外,建議你添加一個外鍵屬性去表示對象直接的依賴關系。
遵循以下格式將表示一個外鍵的關系:<導航屬性名稱><被導航實體的主鍵名稱>,<被導航實體的類名稱><被導航實體的主鍵名稱>,或者<被導航實體的主鍵名稱>,如果找到了多個這樣的匹配關系,將按照上面所給出的先后順序來推斷。外鍵檢測是不區分大小寫的。
當檢測到一個外鍵屬性, Code First基於可空的外鍵推斷出關系。如果屬性是可空的表示這個關系是可選的,否則這個關系將是必須注冊的。
如果外鍵依賴的實體是不可空的, Code First 將設置級聯刪除的關系。如果外鍵依賴的實體是可空的,Code First將不設置級聯刪除關系,當引用的實體刪除時,外鍵將被設置為null。更加多樣的級聯刪除我們可以通過使用fluent API.來重新設置約定。
在如下的例子中導航屬性和外鍵將被用於定義Department 和Course 類之間的關系。
public class Department { // Primary key public int DepartmentID { get; set; } public string Name { get; set; } // Navigation property public virtual ICollection<Course> Courses { get; set; } } public class Course { // Primary key public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } // Foreign key public int DepartmentID { get; set; } // Navigation properties public virtual Department Department { get; set; } }
注意:如果存在多個相同類型之間的關系(比如,假設你定義了Person and Book類,Person 類包含了 ReviewedBooks and AuthoredBooks這兩個導航屬性,同時Book類又包含了 Author and Reviewer導航屬性 )你需要手動的通過Data Annotations 或者 the fluent API來配置關系。更多信息,請參考 Data Annotations - Relationships 和Fluent API - Relationships.
復制類型約定
當Code First發現一個類的主鍵無法推測, 並且沒有通過data annotations 或者fluent API來標識,那么這個類型將自動被當成一個復雜類型來處理,復雜類型要求它不存在引用其他實體類型的屬性。
下面的類Details 將被當成復雜類型,因為它沒有設置主鍵
public partial class OnsiteCourse : Course { public OnsiteCourse() { Details = new Details(); } public Details Details { get; set; } } public class Details { public System.DateTime Time { get; set; } public string Location { get; set; } public string Days { get; set; } }
連接字符串約定
學習更多關於 DbContext連接的約定可以查看 Connections and Models.
移除約定
在命名空間System.Data.Entity.ModelConfiguration.Conventions中,你可以移除約定,以下例子將移除PluralizingTableNameConvention.
public class SchoolEntities : DbContext { . . . protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Configure Code First to ignore PluralizingTableName convention // If you keep this convention, the generated tables // will have pluralized names. modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } }
自定義約定
自定義約定在EF6開始支持,更多信息請查看 Custom Code First Conventions.
老外的文章真的是寫得非常精彩,所以我強烈建議大家去看英文技術博客和文章,看不懂就硬着頭皮看,久了自然就看得懂了,一開始即使看不懂文字說明,看看代碼也好呀。
由於本人英文實在太爛,所以如果有翻譯得不通順的地方還忘見諒,大家可以參考原文,原文地址:Entity Framework Code First Conventions