在本节中,您将使用实体框架代码先行迁移功能对模型类进行修改,并使修改应用到数据库中。
默认情况下,当您使用实体框架代码先行自动创建一个数据库,像你在本教程前面做的那样,代码首先添加一张表到数据库中,以帮助跟踪数据库架构是否是同步的模型类是产生的。如果它们不同步,实体框架抛出一个错误。这使得它更容易在早期开发时跟踪发现问题,否则,你可能在运行时发现隐晦错误。
为模型修改建立代码先行迁移
如果您使用的是Visual Studio 2012,在“解决方案资源管理器”中双击Movies.mdf的文件,打开数据库工具。Visual Studio Express for Web将显示“数据库资源管理器,Visual Studio2012将显示”服务器资源管理器“。如果您使用的是Visual Studio 2010中,使用SQL Server对象资源管理器。
在数据库工具中,在MovieDbContext上右键点击并选择删除。
回到解决方案资源管理器。在 Movies.mdf file文件上右键单击并选择删除。
译者注:此处看上去很费解,事实上,第一步实际执行的操作是删除数据库链接,弹出的删除确认提示也说明了这一点,第二步则是在解决方案管理器里真正删除数据库文件。
生成应用程序,确认没有编译错误。
在vs2012工具菜单里,点击“库程序包管理器”-》程序包管理器控制台
在控制台的PM>标记后,输入“Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDbContext”
输出如下信息:
PM> Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDbContext
正在检查上下文的目标是否为现有数据库...
已为项目 MvcMovie 启用 Code First 迁移。
PM>
上面的Enable-Migrations命令创建了一个新的Migrations文件夹,并在该目录下创建了Configuration.cs文件。
使用Visual Studio打开Configuration.cs文件。使用以下代码替换Seed方法内容:
protected override void Seed(MvcMovie.Models.MovieDbContext context) { context.Movies.AddOrUpdate( m => m.Name, new Movie { Name = "少年派的奇幻漂流之旅",Date=DateTime.Now }, new Movie { Name = "一九四二", Date = DateTime.Now }, new Movie { Name = "王的盛宴", Date = DateTime.Now } ); }
以上代码需要类中导入名称空间using MvcMovie.Models;
代码先行迁移机制在每次迁移后调用Seed方法,如果存在行数据,则该方法更新现有数据,如果不存在,则该方法插入数据。
按下CTRL+SHIFT+B来生成项目(如果此处不执行此生成操作,后续的步骤会失败)
下一步是创建DbMigration 类来初始化迁移。迁移将创建一个新的数据库,这也是在前面步骤中删除数据库文件的原因。
在程序包管理器控制台窗口,输入命令"add-migration Initial"来创建初始迁移。其中Initial可以是任意名称,用来标识创建的初始文件。控制台输出如下:
PM> add-migration Initial
正在为迁移“Initial”搭建基架。
此迁移文件的设计器代码包含当前 Code First 模型的快照。在下一次搭建迁移基架时,将使用此快照计算对模型的更改。如果对要包含在此迁移中的模型进行其他更改,则您可通过再次运行“Add-Migration 201212060747227_Initial”重新搭建基架。
PM>
代码先行迁移机制在Migrations文件夹下创建另外一个类文件,文件名为时间戳+下划线+ Initial.cs,例如201212060747227_Initial.cs,该类包含了创建数据库架构的代码。迁移文件名预置为时间戳有助于排序。查看该文件,包含了创建Movie库表的说明。当你更新数据库时,该类将被执行,创建数据库架构。随后,Seed方法将被执行,测试数据被添加其中。
在程序包管理器控制台窗口,键入"update-database"命令来创建数据库和执行Seed方法。
PM> update-database
指定“-Verbose”标记以查看应用于目标数据库的 SQL 语句。
正在应用基于代码的迁移: [201212060747227_Initial]。
正在应用基于代码的迁移: 201212060747227_Initial。
正在运行 Seed 方法。
PM>
如果遇到表已存在的错误而不能创建,很可能是你删除数据库后,执行update-database前运行了应用程序(重新编译程序,自动创建了数据库)。这种情况下,再次删除数据库文件,并执行 update-database命令。如果仍然出错,删除migrations目录和内容,重新开始本教程操作。
运行应用程序,导航到 /Movies 地址。种子数据显示出来了。
译者注:此处的种子数据,实际上指的是一些库表创建后添加的一些测试数据或者系统初始化数据,如系统参数,部门的根目录等。
为Movie模型增加评价属性
为已存在的影片类增加评价属性。打开 Models\Movie.cs文件,增加Rating属性如下
public string Rating { get; set; }
通过生成菜单或者CTRL+SHIFT+B快捷键编译应用程序。
现在你已经更新了模型类,同样需要更新 \Views\Movies\Index.cshtml 和\Views\Movies\Create.cshtml 视图模板。
打开\Views\Movies\Index.cshtml 文件,在Price列后增加列标题<th>Rating</th>。然后在模板结尾附近增加<td> 列标签。
Create视图中也做相应修改,此处不再详细描述。
现在你已经更新了程序代码来支持新增的评价属性。运行程序并导航到 /Movies ,你会发现以下错误:
支持“MovieDbContext”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。
发生该错误的原因是你在程序中更新了Movie模型类,与已存在的数据库中的Movie库表结构不同(数据库Movie表中没有Rating列)。
解决此问题,有以下几种方法:
1. 令 Entity Framework依据新模型类架构自动删除和重新常见数据库。该方法非常适用于开发在测试数据上进行动态开发;可以使你快速演化模型和数据库表结构。不过,其缺点是,会丢失当前数据库中已存在的数据—因此你不想在生产数据库上使用这种方法。在测试数据库上采用初始化器来自动产生数据库通常是一种高效开发应用程序的方式。想查看更多关于Entity Framework初始化器方面的信息,请参阅Tom Dykstra写的 ASP.NET MVC/Entity Framework tutorial.
2. 显式地修改现有的数据库架构,以便它匹配模型类。这种方法的优点是保留了现存数据。你可以通过手动或者创建一个数据库脚本来做变更。
3. 使用代码先行迁移来更新数据库架构
在这个课程中,我们将使用上面所说的第三种方式,即代码先行迁移
更新Seed方法,使其为新增的列提供值。打开Migrations\Configuration.cs文件,为每个Movie对象增加Rating值。
生成解决方案,然后打开库管理器控制台窗口,输入以下命令add-migration AddRatingMig
add-migration 命令告诉迁移框架对比当前模型和库表结果差异,生成必要的代码来使库表跟模型适配。AddRatingMig名字可以是任意的,只是迁移文件的标识符。采用有意义的名字有助于迁移操作。
当命令执行完毕后,Visual Studio打开类文件,创建了新的DbMIgration 类,在其Up方法里,你可以看到创建新列的代码。
public partial class AddRatingMig : DbMigration { public override void Up() { AddColumn("dbo.Movies", "Rating", c => c.String()); } public override void Down() { DropColumn("dbo.Movies", "Rating"); } }
生成解决方案,库管理器控制台窗口输入"update-database"命令。
PM> update-database
指定“-Verbose”标记以查看应用于目标数据库的 SQL 语句。
正在应用基于代码的迁移: [201212060835020_AddRatingMig]。
正在应用基于代码的迁移: 201212060835020_AddRatingMig。
正在运行 Seed 方法。
PM>
运行应用程序,导航到/Movies,你将看到新增的Rating列
同样,你需要修改Edit和Delete视图,增加Rating属性。
你可以再次在库管理器控制台里输入"update-database”命令,发现没有修改被应用,因为当前数据库表结构跟模型匹配。
在本节中,你学习了如何修改模型对象,并保持与数据库同步。同时学习了如何创建带有示例数据的数据库的方法。下面我们将学习如何为模型类添加验证逻辑使业务规则生效。
译者注:本文说的比较零散,在此做下总结,要使用代码先行提供的迁移功能来保证模型和数据库自动匹配,需要在库程序包管理器里依次执行以下命令:
1.启用迁移功能:Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDbContext
2.建立初态:add-migration Initial
3.自动比对差异生成迁移类:add-migration AddRatingMig
4.将迁移应用到数据库:update-database
在实际的项目开发过程或者维护过程中,因为业务需求或者设计的变动,经常需要对库表增删字段,在项目团队多人合作方式开发情况下,很容易遗漏对数据库的修改,而迁移功能就很好地保证了这一点,“自动”记录了模型变动需要对库表进行的变更操作。
本教程所有文章导航
本系列共10篇文章,翻译自Asp.Net MVC4 官方教程,由于本系列文章言简意赅,篇幅适中,从一个示例开始讲解,全文最终完成了一个管理影片的小系统,非常适合新手入门Asp.Net MVC4,并由此开始开发工作。
原文供9篇文章,译者将其中第6篇拆成了2篇
1. Asp.Net MVC4 入门介绍
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/03/2800210.html
2. 添加一个控制器
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-controller
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801949.html
3. 添加一个视图
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-view
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801988.html
4. 添加一个模型
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-model
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803012.html
5. 从控制器访问数据模型
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803429.html
6.查看Edit方法和Edit视图
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2804100.html
http://www.cnblogs.com/seawaving/archive/2012/12/06/2804590.html
7. 为Movie模型和库表添加字段
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2805401.html
8. 为模型添加验证
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2806322.html
9. 查看Detail和Delete方法
· 译文地址:http://www.cnblogs.com/seawaving/archive/2012/12/10/2811064.html