如今咱们已经将应用程序修改完毕,在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(电影等级)字段的数据能正常追加并在电影清单画面中正常显示,如图所示:
数据模型类的改变会形成数据库重建,因此从此咱们会对这个安全问题进行控制处理。