Entity Framework 簡(jiǎn)言之就是一個(gè)ORM(Object-Relational Mapper)框架. Code First 使得你能夠通過C#的類來描述一個(gè)模型,,模型如何被發(fā)現(xiàn)/檢測(cè)就是通過一些約定(Conventions),。Conventions 就是一系列規(guī)則的集合,,被用于對(duì)基于類別定義的概念模型的自動(dòng)裝配,。 這些約定都被定義于 System.Data.Entity.ModelConfiguration.Conventions 命名空間下,。 當(dāng)然你可以進(jìn)一步地對(duì)你的模型作出配置,例如使用 DData Annotations ,,然后是 ata Annotations 或者 Fluent API. 推薦的配置順序如下:優(yōu)先使用 Fluent API ,,最后才是 Conventions. 本文將會(huì)給出一個(gè)關(guān)于 Conventions 的初步介紹,具體詳細(xì)的列表請(qǐng)參考 http://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions(v=vs.103).aspx 一,、類型發(fā)現(xiàn)約定Type Discovery 當(dāng)我們使用 Entity Framework 進(jìn)行開發(fā)的時(shí)候,,通常是以構(gòu)建一些定義概念模型的類開始,除此之外,,我們還需要讓 DbContext 知道哪些類型需要包含在此模型中,,為了達(dá)到此目的,我們又會(huì)定義一個(gè)繼承自 DbContext 并且為這些類型暴露 DbSet 屬性,。這樣 Code First 將包含這些類型以及這些類型的引用類型(即便引用類型定義于不同的程序集中) 如果類型位于繼承體系中,,也只需為基類(base class)定義 DbSet 屬性,那么位于同一程序集中的派生類型也將被自動(dòng)包含與其中,。 下面的例子中,在類 SchoolEntities 中只定義了一個(gè) DbSet 屬性 Departments . Code First 能夠發(fā)現(xiàn)并鉆取所有的引用類型 usingSystem; usingSystem.Collections.Generic; usingSystem.Data.Entity; usingSystem.Linq; usingSystem.Web; namespaceContosoUniversity.DAL { publicclassSchoolEntities : DbContext { publicDbSet<Department> Departments { get; set; } } publicclassDepartment { //Primary key publicintDepartmentID { get; set; } publicstringName { get; set; } //Navigation property publicvirtualICollection<Course> Courses { get; set; } } publicclassCourse { //Primary key publicintCourseID { get; set; } publicstringTitle { get; set; } publicintCredits { get; set; } //Foreign key publicintDepartmentID { get; set; } //Navigation properties publicvirtualDepartment Department { get; set; } } publicpartialclassOnlineCourse : Course { publicstringURL { get; set; } } publicpartialclassOnsiteCourse : Course { publicstringLocation { get; set; } publicstringDays { get; set; } publicSystem.DateTime Time { get; set; } } } 如果你想排除模型中的某個(gè)類型,,你可以使用 NotMapped屬性(Attribute)或者 DbModelBuilder.Ignore fluent API. [NotMapped] publicclassDepartment NotMapped 位于 System.ComponentModel.DataAnnotations.Schema 命名空間下 protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Ignore<Department>(); } 二,、主鍵約定 Primary Key Convention 如果類中的屬性(Property)名稱為 ID (不區(qū)分大小寫)或 ClassNameID(類名 ID),Code First 則推斷這個(gè)屬性為主鍵,。如果主鍵屬性的類型為數(shù)字型或 GUID 則會(huì)被當(dāng)成標(biāo)識(shí)列(Identity Column) publicclassDepartment { //Primary key publicintID { get; set; } //Primary key publicintDepartmentID { get; set; } } 三、關(guān)系(外鍵/導(dǎo)航屬性)約定 Relationship(Foreign Key/Navigation Properties) Convention 在 Entity Framework中,,導(dǎo)航屬性(Navigation Properties)提供了一種對(duì)兩個(gè)實(shí)體類型之間關(guān)系的驅(qū)動(dòng),每一個(gè)對(duì)象都能擁有它所參與的每一個(gè)關(guān)系的導(dǎo)航屬性(每一個(gè)對(duì)象的每一個(gè)關(guān)系都能有一個(gè)導(dǎo)航屬性),,導(dǎo)航屬性提供在兩端來驅(qū)動(dòng)或操作這個(gè)關(guān)系,,也可以返回任何一方的引用對(duì)象(對(duì)象間的關(guān)系是 1:1 或者 1:0 )或 對(duì)象的集合(對(duì)象間的關(guān)系為 1:* 或*:*), Code First 根據(jù)定義于類型上的導(dǎo)航屬性能夠推斷這種關(guān)系 除了導(dǎo)航屬性外,推薦的方式是再包含外鍵屬性(Foreign Key),。Code First 能夠推斷如下的命名屬性為外鍵(外鍵屬性命名的默認(rèn)約定): <導(dǎo)航屬性名><主體主鍵屬性名>; <主體類名><主鍵屬性名>; <主體主鍵屬性名> 優(yōu)先順序?yàn)閺纳系较拢ǘ鄠€(gè)滿足匹配/約定的時(shí)候),。外鍵屬性命名約定也是大小寫不敏感的。(PS: 個(gè)人覺得把 Principal 譯為主體,,Dependent Entity 譯為從屬實(shí)體較為穩(wěn)妥,,分別對(duì)應(yīng)主從關(guān)系) 當(dāng)外鍵屬性被檢測(cè)到,Code First 將會(huì)根據(jù)外鍵的可空性來推斷關(guān)系的具體形式:如果屬性是可空的,,那么關(guān)系將被注冊(cè)為可選的,;否則則被認(rèn)為是必須的,。 如果從屬實(shí)體上的外鍵是不可為空的,Code First 將會(huì)在關(guān)系上設(shè)置級(jí)聯(lián)刪除,,反之,則不會(huì)級(jí)聯(lián)刪除,,并且當(dāng)主體被刪除的時(shí)候,,外鍵將會(huì)被置為 NULL 多說一句:以上所說的關(guān)系多重性(multiplicity)和級(jí)聯(lián)刪除可以被 Fluent API 重載(覆寫) 以下示例展示用導(dǎo)航屬性和外鍵來定義類 Department 和 Course之間的關(guān)系 publicclassDepartment { //Primary key publicintDepartmentID { get; set; } publicstringName { get; set; } //Navigation property publicvirtualICollection<Course> Courses { get; set; } } publicclassCourse { //Primary key publicintCourseID { get; set; } publicstringTitle { get; set; } publicintCredits { get; set; } //Foreign key publicintDepartmentID { get; set; } //Navigation properties publicvirtualDepartment Department { get; set; } } 四、Complex Types Conventions 如果 Code First 無法從類定義中推斷出主鍵,,也沒有通過 Data Annotations或 Fluent API注冊(cè)的主鍵,,則此類型自動(dòng)注冊(cè)為Complex Types. Complex Types 此外還要求類型中不能含有對(duì)其它實(shí)體類型的引用,并且其它類型中也不能含有對(duì)本類型引用的屬性集合,。一個(gè)Complex Type 示例如下所示 publicpartialclassOnsiteCourse : Course { publicOnsiteCourse() { Details = newDetails(); } publicDetails Details { get; set; } } publicclassDetails { publicSystem.DateTime Time { get; set; } publicstringLocation { get; set; } publicstringDays { get; set; } } 五,、移除約定(Removing Conventions) 可以移除任何定義于命名空間 System.Data.Entity.ModelConfiguration.Conventions 中的約定,如下列示例移除約定 PluralizingTableNameConvention publicclassSchoolContext : DbContext { protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } } 說明:本文是在學(xué)習(xí) Entity Framework Code First Conventions 的隨筆記錄,,對(duì)原文做了一個(gè)意譯以更好地為自己所用,。原文請(qǐng)參考 http://msdn.microsoft.com/en-us/data/jj679962 (推薦閱讀)
|
|