天天看點

使用ASP.NET WEB API建構基于REST風格的服務實戰系列教程(一)——使用EF6建構資料庫及模型

使用Entity Framework Code First模式建構資料庫對象

已經決定使用EF CodeFirst來建立資料庫了,是以我們使用POCO類(“Plain Old CLR Objects)來定義我們的Model。我們通過寫标準的.NET類來定義适合我們API的領域模型。那些POCO類就會為我們建立資料庫。

我們的教育訓練系統資料庫比較簡單,首先我們需要有學生”Students”,導師”Tutors”,除此之外我們還需要定義課程”Courses”以及科目”Subjects”。在我們的系統中,我們允許每個學生去報名參加不同的課程

下圖是我們資料庫建立後的結果,我在這裡列出來的目的是為了幫助大家更好的了解接下來建立的POCO類(圖不是很清晰,湊合看吧):

使用ASP.NET WEB API建構基于REST風格的服務實戰系列教程(一)——使用EF6建構資料庫及模型

第一步:建立一個空的類庫項目

打開VS,建立一個空的類庫項目

使用ASP.NET WEB API建構基于REST風格的服務實戰系列教程(一)——使用EF6建構資料庫及模型

.NET Framewok版本的話我用的事4.5的,選4.0的也行

第二步:使用NuGet添加Entity Framework的引用

右擊引用->管理NuGet程式包->右上角輸入Entity Framework,選擇安裝。裝好之後就應該是這麼一個樣子:

使用ASP.NET WEB API建構基于REST風格的服務實戰系列教程(一)——使用EF6建構資料庫及模型

這裡用的是Entity Framework6,因為這個版本支援了枚舉類型,在這次的項目裡也有涉及

第三步:建立Model

前面已經說了,到目前為止我們還沒有資料庫。是以我們需要寫标準的.NET類來定義領域模型并幫我們生成資料庫

建立一個Entities檔案夾并建立5個類(“Student”,“Course”,“Subject”,“Tutor”,“Enrollment”),這幾個簡單的實體類将為我們建立資料庫

不難發現,上面我們建立的Model并沒有從任何基類繼承,也沒有打任何attributes。有哪些标準的話會使我們的資料通路擁有更好的延展性,這樣的話我們就可以專心地去處理業務而不用過多地考慮資料的持久化。 

Entity framework Code First預設使用一種叫“約定大于配置”的方式來為我們建立資料庫(通過POCO類映射資料庫的表,字段的資料類型,外鍵等)。在一些簡單的應用程式中來說是非常好用的。但在我們的項目中将使用Fluent API配置我們自定義的資料庫生成規則——“配置覆寫約定”

第四步:應用自定義映射規則

當我們決定使用配置來覆寫預設規則時,我們可以為每張表的字段配置資料類型,是否可空,表與表之間外鍵關系,主鍵以及辨別列等等。

于是乎我們建立一個“Mappers”檔案夾,建立5個繼承自System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<T>的類。分别命名為: “CourseMapper”, “EnrollmentMapper”, “StudentMapper”, “SubjectMapper”, and “TutorMapper”

看看上面的代碼,不難發現我們為每個POCO類屬性(資料類型,是否為空,主鍵辨別,外鍵關系)都做了配置。這些配置最終會影響我們資料庫中表的建立。

第五步:建立Context類來實作資料持久化

現在我們要建立一個LearningContext類繼承自System.Data.Entity.DbContext:

這個LearningContext類主要有三大任務

1.把我們定義的POCO類作為DBSet的屬性對外公開,這意味着每一個POCO類都将被轉化為資料庫中的表

2.重寫OnModelCreating方法将我們為POCO類自定義的映射規則添加到DbModelBuilder配置中

3.在LearningContext的構造函數中我們做了2件事:

     (1)将ProxyCreationEnabled和LazyLoadingEnabled 2個屬性設為false(預設都是true)。延遲加載(LazyLoading)主要是指當對象間的關聯配置成導航屬性暴露給外界的時候,那麼這個屬性的會在用到它的時候(在前台foreach的時候)才加載,那麼極有可能成為性能殺手,我們項目中希望立即加載。而ProxyCreation是配合LazyLoading一起用的,是以當我們把這兩個屬性值設為false時,那麼“LearningContext”就不會去加載導航屬性除非調用了“Include”方法(下一章會有示範)。

      (2)為資料庫配置初始化和遷移政策,如果模型的屬性被改變(添加了新的屬性),就把資料庫遷移到最新版本。為了實作這個功能,我們建立一個類LearningContextMigrationConfiguration繼承自System.Data.Entity.Migrations.DbMigrationsConfiguration<TContext>

LearningContextMigrationConfiguration這個類主要有2個任務:

        (1)在構造函數中,我們設定AutomaticMigrationsEnabled 屬性為true,那麼就意味着EF會為我們自動遷移資料庫而不考慮版本問題。同時我們把AutomaticMigrationDataLossAllowed屬性也設為true但這樣做在開發環境中是很危險的,因為如果這個屬性設為false時,一旦資料庫在自動遷移時發生資料丢失,那麼就會抛出一個異常。但在這次的系列中我們確定沒問題。

        (2)重寫Seed方法來為我們的資料庫添加初始資料,這個函數在我們應用程式每次啟動時執行。“LearningDataSeeder”這個類主要用于提供需要的資料,具體代碼在本章結束時提供。

本章總結

到目前為止,我們已經把用于建立資料庫的Model和配置都實作了。在這個時候我們應該想一想:資料通路層是否已經完成?當我們使用Web Api操作的時候是否友善 快捷 高效?我們是否應該對已有的資料通路層再做一次封裝?。。。 是以下一章我們将使用“Repository”模式應用在我們的項目中。