MVC5 + EF6 完整入門教程三
期待已久的EF終於來了。
學完本篇文章,你將會掌握基於EF資料模型的完整開發流程。
本次將會完成EF資料模型的搭建和使用。
基於這個模型,將之前的示例新增資料庫查詢驗證功能。
文章提綱
概述 & 要點
詳細步驟
總結
概述 & 要點
下面是本文要點,正文部分會有詳細介紹。
- EF架構圖
- 新建基於EF的Data Model的約定
- 關於ORM的重要概念,和傳統方式開發的區別
- EF開發的整體過程
詳細步驟
- 新建資料夾,規劃好程式碼擺放位置
- 建立相關類 (Data Model)
- 建立 Database Context
-
建立Initializer, 使用EF初始化資料庫,插入示例資料
- 完成資料庫查詢驗證
新建資料夾,規劃好程式碼擺放位置
- 根目錄下新建一個ViewModels資料夾。
Models資料夾裡面存放對應於資料庫表的實體。
View中需要顯示的資料和Models中實體模型不一定能對應上, 因此需要專門給View使用的自定義資料模型,我們稱之為ViewModel , 放在ViewModels資料夾裡面。
- 根目錄下新建一個DAL 資料夾。
DAL 放置資料訪問相關類。
NOTE 本文中放AccountContext.cs, AccountInitializer.cs
建立相關類(Data Model)
為了更加貼近真實情況,我們針對使用者建立三個相關的類。
SysUser, SysRole, SysUserRole
這是使用者許可權管理RBAC (Role – Based Access Control)的一個典型模型, 更復雜的模型都可以在這個基礎上進行擴充套件。
OK,下面我們就開始新建這個模型。
我們先去網上找個大致的關係圖做參考,開啟百度,輸入 user role , 搜尋圖片。
挑一個類似的做參考。
NOTE 許可權相關是系統管理範疇的,不涉及具體業務,我起名字的時候都加了Sys字首,這樣和業務區隔開來。
參考上面這個圖建立 Data Model
SysUser Entity
SysRole Entity
SysUserRole Entity
對於上面幾個類的約定和說明:
- EF生成資料庫時,ID 屬性將會成為主鍵。(約定:EF預設會將ID或classnameID生成主鍵, MSDN建議保持風格的一致性, 都用ID或classnameID, 我們這裡都用ID)
-
EF 生成資料庫時 , <navigation property name><primary key property name>這種形式的會成為外來鍵. ( 約定 )
例如外來鍵 SysUserID = SysUser(navigation property)+ID(SysUser的主鍵)
-
定義為virtual的幾個屬性是 navigation 屬性(virtual非必須, 只是慣例用法, 後面文章將會講解用virtual的好處).
navigation 屬性儲存著其他的關聯entity(entities)
示例中, SysUser和SysUserRole是一對多的關係, SysRole和SysUserRole也是一對多的關係.
如果是 "多", 屬性型別就必須是list( 這裡用的是Icollection )
建立 Database Context
前置條件:安裝EF
開啟 工具à庫程式包管理器à程式包管理器控制檯
輸入 install-package entityframework
從上圖可以看出,EF框架在底層是通過呼叫ADO.NET來實現資料庫操作的。
多轉一道彎效能和靈活性肯定會受到影響,所以本系列文章結束後同樣也會給出MVC+ADO.NET的方案,大家可以根據需要選擇。
NOTE
微軟官方推出的ORM框架主要有Linq to SQL和Entity Framework.
EF是目前最新的,也是推薦配合MVC使用的框架。
實際操作前再補充一些重要概念:
如果不用ORM框架,我們一般這樣來使用ADO.NET進行資料庫開發:
- 將ADO.NET對資料庫的操作封裝到一個類裡SqlHelper中
- 在DAL層呼叫SqlHelper
- 其他層再呼叫DAL進行資料庫操作
使用ORM之後,以前面的SysUser為例:
O(Object) à 程式中的類 SysUser, 就是物件
R (Relation)à 資料庫中的表
M(Mapping)à O和R的對映關係
ORM對傳統方式的改進:
充當橋樑,實現了關係資料和物件資料的對映,通過對映自動產生SQL語句。
對常用的操作,節省了寫SQL語句的步驟。
好了,現在必要的概念應該理解了吧,下面我們就進行實際的操作了。
建立類 AccountContext.cs , 讓他繼承自System.Data.Entity.DbContext, 我們用這個類完成EF的功能。
主要做下面三件事:
-
為每個entity set建立一個DbSet
在EF中,通常情況下一個entity set對應資料庫中的一張表,一個entity對應表中的一行。
-
指定一個連線字串
建構函式中的 base("AccountContext") 。
預設情況下和類名一樣,即AccountContext,我們顯式的給他指定出來。
-
指定單數形式的表名
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
預設情況下會生成複數形式的表,如SysUsers
NOTE 表名用單複數形式看各自的習慣,沒有明確的規定。有的公司表名全用單數,有的公司根據表的意思,有單數也有複數。
配合上面第2點,先把web.config中連線字串給指定了。
如下圖,貼著appSettings配置節上面新增。注意要web.config中要加上紅字部分,不然會出錯。
<
connectionStrings
>
<
add
name="AccountContext" connectionString="Data Source=.;database=MvcDemo;uid=sa;pwd=123456;AttachDBFilename=|DataDirectory|\MvcDemo.mdf;"providerName="System.Data.SqlClient"/>
</
connectionStrings
>
NOTE AttachDBFilename=|DataDirectory|\MVCDemo.mdf設定了資料庫檔案的存放位置:在專案根目錄的App_Data資料夾下。
建立Initializer, 使用EF初始化資料庫,插入示例資料
EF可以以多種方式建立資料庫。
我們採用如下方式:
第一次執行程式時新建資料庫,插入測試資料; model改變(和database不一致)時刪除重建資料庫,插入測試資料。
目前在開發階段,不用管資料丟失的問題,直接drop and re-create比較方便。
等系列文章結束後會講解生產環境中如何不丟失資料修改schema
下面我們就新建類AccountInitializer.cs來完成這個工作。
Seed方法用我們之前定義的database context(即AccountContext) 作為引數,通過這個context將entities新增到database中去。(就是我們前面說的橋樑作用)
從上面程式碼可以看出, Seed方法對每一個entity的型別(我們用了SysUser和SysRole, SysUserRole我們暫不新增):
建立一個colletion à 新增到適當的 DbSet propertyà 儲存到資料庫。
NOTE 不一定要在每個entity組後面都呼叫SaveChanges方法,可以在所有組結束後呼叫一次也可以。這樣做是因為如果寫入資料庫程式碼出錯,比較容易定位程式碼的錯誤位置。
修改web.config, 通知EF使用我們剛剛寫好的initializer類。
找到entityFramework配置節,新增下圖方框處內容。
context 配置節中, type 的值對應 (context class的完整描述,程式集)
databaseInitializer 配置節中 , type 的值對應 (initializer class 的完整描述,程式集)
NOTE : 如果你不想EF使用某個context, 可以將下面方框處設定為true.
完成資料庫查詢驗證
現在EF一切就緒.
執行程式,當第一次連線資料庫時,EF比較model(AccountContext和entity classes) 和database. 如果兩邊不一致,程式將會drop and re-create資料庫。
因為目前我們還沒有連線資料庫的操作,所以EF還沒發揮作用。
現在我們完成前面的Login功能。
-
先做點小修改,在ModelsàSysUser.cs裡面添加個Email欄位。
同樣DALàAccountInitializer.csàSeed裡面示例資料也要增加這個欄位
NOTE 新增一個Email是因為之前的登入頁面填入的是Email值,後面將會輸入Email和Password到資料庫中進行比對。
-
開啟Controllersà AccountController.cs
- Instantiate 一個database context 物件
- 修改HttpPost型別的Login Action,查詢資料庫進行比對。
NOTE
用過SQL的人都知道,學習SQL,最複雜的是查詢,把各種查詢學好了,基本就掌握70%以上了。
EF資料模型的資料操作也一樣,重點是查詢,下篇文章會展開講。(從簡單查詢到條件、聚合、連線等複雜查詢都會涉及到)
執行Login.cshtml頁面,輸入正確的和錯誤的登入資訊驗證下。
另外再檢查一下資料庫部分是否符合我們的預期:
- 開啟資料庫,發現MVCDemo這個資料庫已經新建,示例資料已經插入。
- 開啟專案的App_Data 資料夾,發現數據庫檔案已經存在。
總結
OK,到此為止,我們搭建好了EF框架,進行了資料庫的初始化,查詢了一條使用者資訊。
需要說明的是,現在的登入功能還比較簡陋,不是真正的登入功能(例如輸入項還缺少驗證,密碼還沒有加鹽),只是為了說明EF的用法。根據系列文章講述知識點的需要,最終會實現完整功能。
最後再回顧下本篇文章的重點:掌握使用EF開發的整個過程。
建立Data Modelà建立Database Contextà建立databaseInitializerà配置entityFramework的context配置節
希望大家能清晰的瞭解上面整個過程,理解每一個過程的作用。
好了,本次文章就到這裡。
歡迎大家多提問題多評論,讓下一篇文章更好 :)