MVC基於EF的架構

文章提綱

概述 & 要點

詳細步驟

總結

概述 & 要點

下面是本文要點,正文部分會有詳細介紹。

  • EF架構圖

  • 新建基於EF的Data Model的約定

  • 關於ORM的重要概念,和傳統方式開發的區別

  • EF開發的整體過程

詳細步驟

  • 新建文件夾,規劃好代碼擺放位置

  • 創建相關類 (Data Model)

  • 創建 Database Context

  • 創建Initializer, 使用EF初始化數據庫,插入示例數據

  • 完成數據庫查詢驗證

新建文件夾,規劃好代碼擺放位置

  1. 根目錄下新建一個 ViewModels文件夾。

           Models文件夾裏面存放對應於數據庫表的實體。

           View中需要顯示的數據和Models中實體模型不一定能對應上, 因此需要專門給View使用的自定義數據模型,我們稱之爲ViewModel , 放在ViewModels文件夾裏面。

  1. 根目錄下新建一個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

對於上面幾個類的約定和說明:

  1. EF生成數據庫時,ID 屬性將會成爲主鍵。(約定:EF默認會將ID或classnameID生成主鍵, MSDN建議保持風格的一致性, 都用ID或classnameID, 我們這裏都用ID)

  2. EF 生成數據庫時 , <navigation property name><primary key property name>這種形式的會成爲外鍵. ( 約定 )

    例如外鍵 SysUserID = SysUser(navigation property)+ID(SysUser的主鍵)

  3. 定義爲virtual的幾個屬性是 navigation 屬性(virtual非必須, 只是慣例用法, 後面文章將會講解用virtual的好處).

    navigation 屬性保存着其他的關聯entity(entities)

    示例中, SysUser和SysUserRole是一對多的關係, SysRole和SysUserRole也是一對多的關係.

    如果是 "多", 屬性類型就必須是list( 這裏用的是Icollection )

創建 Database Context

前置條件:安裝EF

打開 工具à庫程序包管理器à程序包管理器控制檯

輸入 install-package entityframework

去MSDN上查看下EF的架構圖:http://msdn.microsoft.com/en-us/data/aa937709

從上圖可以看出,EF框架在底層是通過調用ADO.NET來實現數據庫操作的。

多轉一道彎性能和靈活性肯定會受到影響,所以本系列文章結束後同樣也會給出MVC+ADO.NET的方案,大家可以根據需要選擇。

NOTE

微軟官方推出的ORM框架主要有Linq to SQL和Entity Framework.

EF是目前最新的,也是推薦配合MVC使用的框架。

實際操作前再補充一些重要概念:

如果不用ORM框架,我們一般這樣來使用ADO.NET進行數據庫開發:

  1. 將ADO.NET對數據庫的操作封裝到一個類裏SqlHelper中

  2. 在DAL層調用SqlHelper

  3. 其他層再調用DAL進行數據庫操作

使用ORM之後,以前面的SysUser爲例:

O(Object) à 程序中的類 SysUser, 就是對象

R (Relation)à 數據庫中的表

M(Mapping)à O和R的映射關係

ORM對傳統方式的改進:

充當橋樑,實現了關係數據和對象數據的映射,通過映射自動產生SQL語句。

對常用的操作,節省了寫SQL語句的步驟。

好了,現在必要的概念應該理解了吧,下面我們就進行實際的操作了。

創建類 AccountContext.cs , 讓他繼承自System.Data.Entity.DbContext, 我們用這個類完成EF的功能。

主要做下面三件事:

  1. 爲每個entity set創建一個DbSet

    在EF中,通常情況下一個entity set對應數據庫中的一張表,一個entity對應表中的一行。

  2. 指定一個連接字符串

    構造函數中的 base("AccountContext") 。

    默認情況下和類名一樣,即AccountContext,我們顯式的給他指定出來。

  3. 指定單數形式的表名

    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功能。

  1. 先做點小修改,在ModelsàSysUser.cs裏面添加個Email字段。

    同樣DALàAccountInitializer.csàSeed裏面示例數據也要增加這個字段

NOTE 添加一個Email是因爲之前的登錄頁面填入的是Email值,後面將會輸入Email和Password到數據庫中進行比對。

  1. 打開Controllers à AccountController.cs

    1. Instantiate 一個database context 對象

    2. 修改HttpPost類型的Login Action,查詢數據庫進行比對。

NOTE

用過SQL的人都知道,學習SQL,最複雜的是查詢,把各種查詢學好了,基本就掌握70%以上了。

EF數據模型的數據操作也一樣,重點是查詢,下篇文章會展開講。(從簡單查詢到條件、聚合、連接等複雜查詢都會涉及到)

運行Login.cshtml頁面,輸入正確的和錯誤的登錄信息驗證下。

另外再檢查一下數據庫部分是否符合我們的預期:

  1. 打開數據庫,發現MVCDemo這個數據庫已經新建,示例數據已經插入。

  2. 打開項目的App_Data 文件夾,發現數據庫文件已經存在。

     

總結

OK,到此爲止,我們搭建好了EF框架,進行了數據庫的初始化,查詢了一條用戶信息。

需要說明的是,現在的登錄功能還比較簡陋,不是真正的登錄功能(例如輸入項還缺少驗證,密碼還沒有加鹽),只是爲了說明EF的用法。根據系列文章講述知識點的需要,最終會實現完整功能。

最後再回顧下本篇文章的重點:掌握使用EF開發的整個過程。

創建Data Modelà創建Database Context à創建databaseInitializerà配置entityFramework的context配置節

希望大家能清晰的瞭解上面整個過程,理解每一個過程的作用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章