簡單MVC搭配Code First的Entity Framework,包括自動Migrate功能

簡單MVC搭配Code First的Entity Framework,包括自動Migrate功能

  1. EF裏面使用Code First方式來創建DB
  2. 使用做出來的Model在創建出Controller和View
  3. 使用VS 2012 Page Inspector來找出View項目的位置
  4. 學習更改Model來更改View,同時加上一些驗證
  5. 如何在更改Model的類別定義以後Migrate回去更新DB

前言

這篇介紹了簡單的製作一個CRUD MVC網站,搭配使用Code First來創建DB和Migrate來更新DB。

同時介紹了一些Visual Studio 2012 工具使用。

 

1. EF使用Code First

當開出一個「MVC Internet Application(網際網路應用程式)」的時候,我們可以再Model的資料夾下面加上一個「類別(Class)」,這一個Class將會是我們的Code First的Class。

首先,Class就會對應成為一個DB裡面的Table,而每一個Class裡面的Property則會對應到DB Table裡面的Column。因此我們可以使用「Prop」這一個Code Snippet快速的為Class加上需要的Property。以我的例子,是做一個新聞資料的Class:

3289109

創建好了以後,記得要先Build(建制)一些,不然Controller那邊會找不到

2. 使用Model Class作出Controller和View

當Class定義好了以後,我們可以使用他來作出Controller和View。首先,在Controller資料夾那邊新增一個Controller,然後「Scaffolding Options」「Template」選擇第二個「Mvc Controller With read/write action and Views using Entity Framework」。「Model Class」選擇剛剛創建的Model Class,「Context」則是EF對應的,目前來說選則「UsersContext」:

4224288

這就會作出Controller和View。

3. 使用VS 2012 Page Inspector來找出修改位置

VS 2012 提供了「Page Inspector」的Debug方式,使得找到網頁修改位置和Css對應資料變得很簡單。

只要更改Debug模式到「Page Inspector」執行即可:

4900506

執行以後,只要點選右下角的「Inspect」然後找到想看的元素,在右邊將會出現那個元素的Html在哪一行同時在哪一個文件。

4612325

注意到下面有一個「Trace Style」,可以看到目前哪一個CSS有Apply,同時可以動態修改。如果想要直接修改CSS檔案,可以點選每一個對應的CSS然後會帶到Css檔案那一頁:

4835952

4. 更改Model達到更改View

使用了「Page Inspector」,我們知道那裡可以直接更改頁面,不過MVC提供更好的方法,只要更改Model對應的View會直接改變,同時也可更改View裡面的驗證訊息和所需要的驗證。

以上都是使用C# Attribute的方式添加到對應的Property來達到。我想它的原理應該是到View的時候,這些Attribute會使用Reflector讀取出來然後作出相對應的反應,不過這是題外話而且我也不確定。

首先,介紹Attribute會用到的命名空間(Namespace)。這些都可以使用VS 裡面的Smart Tag使用到:

  • using System.ComponentModel.DataAnnotations;大部份使用到
  • using System.ComponentModel; DisplayName會使用到

然後介紹每一個作用:

  • [Required(ErrorMessage="message")]:使得這一個欄位為必填,同時可以選擇需要顯示的錯誤訊息
  • [StringLenghth(最長值)]:限制這一個欄位的最大值
  • [DataType(DataType的Enum)]:這表示輸入的將會是什麼樣的值。同時View也會給出不同的輸入框。例如:如果設為「MultilineText」則View的輸入框變成 多行的Textbox,如果是「Date」則變成日曆選擇器(只有在Chrome會這樣,IE和FF則不會)。

以上大部份都可以加上「ErrorMessage=message」,而message的string裡面可以加上{0}來傳遞一個參數,而這個參數代表著哪一個Property的DisplayName。

可以看出:

7716854

5. 更改Model類別以後更新(Migrate)DB

5.1 問題描述

目前來說看起來一切正常,不過當你要新增或是進入Index都會出現Exception,而這一個Exception其實就是告訴你:「Model Class的定義被修改了,導致DB裡面的Schema對應不上,請把DB Schema更新。」那麼可能會納悶,為什麼會如此?其實如果你把你的Model Class和DB 裡面Schema對比就會瞭解了。

首先[Required]表示這一欄位一定要有值,所以在DB術語裡面就是不能為null。但是因為你剛建造Model Class的時候沒有使用[Required],所以本來創建出來的DB是允許null。你後來更改,那麼Model Class的定義和DB Schema就起了衝突,因此出現了Exception。

題外話:雖然創建「PublishDate」也沒有給[Required],但是因為它是DateTime Type,而DateTime是Value Type所以不許為空,所以預設是不能為null

其他的驗證和DB Schema的對應以此類推:

8656776

5.2 解決辦法

其實在Exception裡面有告知去哪裡看解決辦法,網址是:http://msdn.microsoft.com/en-us/data/jj591621,而基本上我們只要設定任何Model Class的修改將會直接更新DB,這個動作叫做Migrate。

步奏如下:

  1. 使用「Package Management Console」指令「Enable-migrate」開啟Migrate功能。它將會創建一個「Migration」資料夾裡面包含Migrate的設定,和如果是手動更新DB裡面所保留的每一次動作。

    Package Management Console 在 「View(視窗)」-》「Other Windows(其他視窗)」下面。

    題外話:在「Package Management Console」裡面可以像在CMD一樣,打幾個字然後按下Tab來幫你AutoComplete。
  2. 把「Migration\configuration.cs」裡面的「AutomaticMigrationsEnabled」設置為True同時在它下一行加上AutomaticMigrationDataLossAllowed也設置為True。

    這兩個表示, 首先第一個告訴它每一次執行,都自動幫我們做Migrate的動作。而第二個則表示,你知道你所修改的定義可能會造成資料損失。舉例來說,本來一個欄位沒有設定大小,現在 最大只有16個字,那麼如果本來存了超過16個字以上的內容將會被刪掉。

  3. 在Global.asax.cs裡面的「Application_Start()」加上:
    Database.SetInitializer(new MigrateDatabaseToLatestVersion()); </BLOGCONTEXT,>

    這邊有三個地方需要注意:

    1. 「Database」需要加上:using System.Data.Entity;
    2. 「Configuration」需要加上:using MvcApplication2.Migrations; MvcApplication2 是我的Namespace,所以一各自不同修改。
    3. 「BlogContext」則是改成創建Controller時候所使用的Context,我的是「UsersContext」同樣需要加Using。

設定完了以後,發現每一次更改Model Class,DB Schema也會跟著改。不過,當你加入新的Property,雖然DB也會增加,但是View是不會增加的。唯一的做法是手動加入。所以使用MVC一定記住,把DB定義好了才開始,這樣會減少很多問題。


Google+

創用 CC 授權條款
Alan Tsai 的隨手筆記Alan Tsai製作,以創用CC 姓名標示 4.0 國際 授權條款釋出。