MVC神韻---你想在哪解脫!(十三)

維護模型與數據庫結構之間的差異

如今咱們已經將應用程序修改完畢,在Movie數據模型中添加了一個Rating屬性。如今讓咱們從新運行應用程序,打開「http://localhost:xx/Movies」這個URL地址,這時,瀏覽器會顯示一個應用程序出錯畫面。如圖所示。數據庫

致使這個問題發生的緣由是由於在應用程序中,更新後的Movie數據模型類與咱們實際鏈接的數據庫結構並不統一(Movies數據表中並無Rating列)。在默認狀況下,當你使用EF code-first自動建立數據庫時,EF code-first會自動在數據庫中追加數據表來使得數據庫的結構與它自動生成的模型類保持同步。若是不一樣步,EF將會拋出一個錯誤。這使得在開發程序時對於錯誤的跟蹤會變得更加容易,不然你只能在運行時發現這個錯誤。同步檢查特性正是引發以上顯示的錯誤的緣由。瀏覽器

有兩種方法能夠解決這個錯誤:安全

1. 讓Entity Framework自動刪除當前數據庫,並在新的模型類的基礎上從新建立該數據庫。這種方法在使用一個測試數據庫時對於開發來講是十分方便的,由於它容許你快速地同步修改模型與數據庫。但缺點是你將丟失現存庫中的數據(因此請不要將這個方法使用在實際使用中的數據庫上)。ide

2. 修改數據庫中的數據表的結構來使之與數據模型相匹配。這個方法的好處是可讓你保留表中的數據。你能夠手工實現這一操做。測試

如今咱們使用第一種方法,在任何模型發生了改變的狀況下讓EF自動重建數據庫。

當模型改變時自動重建數據庫

如今咱們來修改咱們的應用程序,使得咱們的應用程序中若是任何模型發生了改變,都將自動刪除與重建當前模型所使用的數據庫。在解決方案資源管理器中,鼠標右擊Modes文件夾,選擇「添加」,而後點擊「類」,如圖所示:spa

在「添加新項」對話框中,將類名定義爲「MovieIntializer」,而後點擊添加按鈕添加該類。書寫該類的代碼以下所示:3d

using System;
using System.Collections.Generic;
using System.Data.Entity.Database;
namespace MvcMovie.Models
{
    public class MovieIntializer :
DropCreateDatabaseIfModelChanges<MovieDBContext>
    {
        protected override void Seed(MovieDBContext context)
        {
            var movies = new List<Movie> { 
 
                 new Movie { Title = "非誠勿擾 2",  
                             ReleaseDate=DateTime.Parse("2011-1-11"),  
                             Genre="愛情", 
                             Rating="R", 
                             Price=7.00M}, 
 
                 new Movie { Title = "趙氏孤兒",  
                             ReleaseDate=DateTime.Parse("2011-2-23"),  
                             Genre="歷史", 
                             Rating="R", 
                             Price=9.00M},  
             };
 
            movies.ForEach(d => context.Movies.Add(d));
        }
 
    }
}

使用這個MovieInitializer類以後,一旦咱們的數據模型類發生改變後,咱們的模型類所映射的數據庫都會被自動重建。代碼中使用了Seed方法來指定任什麼時候候重建數據庫的時候,想要追加到某數據表中的數據。這爲將一些示例數據添加到數據表中的操做提供了一個有用的方法,而不須要重建了數據庫以後再手工到數據表中添加示例數據。如今咱們已經定義好了咱們的MovieInitializer類,接下來咱們想在整個工程中使用這個類,這樣每次在運行咱們的應用程序的時候會自動檢查當前咱們的模型類結構是否與數據庫結構不一致,若是不一致的時候就自動重建該數據庫,而且追加MovieInitializer類中所指定的默認數據。打開咱們的MvcMovies工程的根目錄下的Global.asax文件,如圖所示:code

Global.asax文件中定義了當前工程所使用到的Application(應用程序)主類,包含了一個Application_Start()事件處理器,當第一次運行咱們的應用程序時會觸發這個事件。讓咱們在文件頭部追加兩個有用的聲明。第一個聲明引用Entity Framework命名空間,第二個聲明引用咱們的MovieInitializer類所存在的命名空間。這兩句聲明的代碼以下blog

using System.Data.Entity.Database;  // DbDatabase.SetInitialize
using MvcMovie.Models;              // MovieInitializer

接下來尋找到Application_Start方法,在該方法的開頭追加一個DbDatabase.SetInitializer()方法,代碼以下:事件

 

protected void Application_Start()
{
    DbDatabase.SetInitializer<MovieDBContext>(new MovieInitializer()); 
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

咱們追加的DbDatabase.SetInitializer方法將會在實際使用的數據庫中的結構與咱們的Movie模型類所映射的數據庫結構不匹配時自動重建該數據庫,而且自動添加MovieInitializer類中所指定的默認數據。(很殘暴的清除了用戶數據)

關閉Global.asax文件從新運行咱們的應用程序,並在瀏覽器中輸入「http://localhost:xx/Movies」。當咱們的應用程序啓動的時候,會自動發現數據模型類結構與數據庫結構再也不匹配,因而刪除並重建該數據庫使之相匹配,而後自動追加默認數據,瀏覽器中顯示結果如圖:

點擊追加按鈕進行數據的追加

點擊追加按鈕後,新追加的包括Rating(電影等級)字段的數據能正常追加並在電影清單畫面中正常顯示,如圖所示:

數據模型類的改變會形成數據庫重建,因此從此咱們會對這個安全問題進行控制處理。

相關文章
相關標籤/搜索