==============================翻译==============================
在这一节中您将使用实体框架代码第一次迁移一些更改迁移到模型的类,所以更改应用到数据库。
默认情况下,当您使用实体框架代码优先将自动创建一个数据库,如你做了较早前在本教程中,代码第一次添加一个表格到数据库,以帮助跟踪数据库的架构是否与它从生成的类模型同步。如果他们不能同步,实体框架将引发错误。这使得它易于在开发时,你可能会否则只发现 (由晦涩错误) 在运行时跟踪问题。
设置代码第一次迁移模型更改
如果您使用的 Visual Studio 2012,请双击解决方案资源管理器,打开数据库工具中的Movies.mdf文件。Visual Studio 速成版为 Web 将显示数据库资源管理器中,Visual Studio 2012 将显示服务器资源管理器。如果您使用的 Visual Studio 2010,使用 SQL 服务器对象资源管理器。
在数据库工具 (数据库资源管理器、 服务器资源管理器或 SQL 服务器对象资源管理器),右键点击MovieDBContext
并选择删除来删除电影数据库。
向后定位到解决方案资源管理器。右键单击Movies.mdf文件并选择删除来删除电影数据库。
生成应用程序,以确保没有任何错误。
从工具菜单上,单击库的软件包管理器,然后程序包管理器控制台.
在程序包管理器控制台窗口中的PM>
提示符下输入“Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext”。
(如上所示) 的启用迁移命令在新的迁移文件夹中创建一个Configuration.cs文件。
Visual Studio 将打开Configuration.cs文件。用下面的代码替换中的Configuration.cs文件的Seed
方法:
protected override void Seed(MvcMovie.Models.MovieDBContext context) { context.Movies.AddOrUpdate( i => i.Title, new Movie { Title = "When Harry Met Sally", ReleaseDate = DateTime.Parse("1989-1-11"), Genre = "Romantic Comedy", Price = 7.99M }, new Movie { Title = "Ghostbusters ", ReleaseDate = DateTime.Parse("1984-3-13"), Genre = "Comedy", Price = 8.99M }, new Movie { Title = "Ghostbusters 2", ReleaseDate = DateTime.Parse("1986-2-23"), Genre = "Comedy", Price = 9.99M }, new Movie { Title = "Rio Bravo", ReleaseDate = DateTime.Parse("1959-4-15"), Genre = "Western", Price = 3.99M } ); }
在Movie
下出现红色波浪线上右键单击并选择解决然后使用MvcMovie.Models ;
这样做将添加以下使用语句:
using MvcMovie.Models;
代码第一次迁移后每一次迁移 (即,调用更新数据库在程序包管理器控制台中),并且此方法更新行的已经插入,或将它们插入,如果它们不存在尚未调用Seed
的方法。
按 CTRL-SHIFT-B 要生成的项目。(以下步骤将会失败,如果你不在此时生成。)
下一步是创建一个DbMigration
类,用于初始迁移。这种迁移到创建新的数据库,这就是为什么你删除前一步骤中的movie.mdf文件。
在程序包管理器控制台窗口中,输入“add-migration Initial”命令来创建初始迁移。名称“Initial”可以是任意的名称,并用于命名所创建的迁移文件。
Code First 迁移会在Migrations文件夹中创建另一个类文件(名称为{DateStamp}_Initial.cs),该类包含用于创建数据库架构的代码。迁移文件名前固定与时间戳以帮助与排序顺序。检查{DateStamp}_Initial.cs文件,它包含为电影 DB 创建电影表的说明。当您按照下面的说明更新数据库时,此{DateStamp}_Initial.cs文件将运行,并创建数据库架构。然后种子的方法将运行来填充的 DB 的测试数据。
在程序包管理器控制台中,输入命令“update-database”来创建数据库并运行Seed方法。
如果您获得了一个错误,指示表已经存在并且无法创建,可能是因为您在删除了数据库但尚未执行update-database
时运行该应用程序。在这种情况下,再次删除Movies.mdf文件,然后重试update-database
命令。如果您仍遇到错误,删除迁移文件夹及其内容,然后开始与顶部的此页面 (也就是的删除Movies.mdf文件然后继续启用迁移) 的说明。
运行该应用程序,然后定位到/Movies的 URL。种子数据显示。
评级属性添加到电影模式
通过将新的Rating
属性添加到现有的Movie
类开始。打开Models\Movie.cs文件并添加像这样的Rating
属性:
public string Rating { get; set; }
完整的Movie
类现在看起来像下面的代码:
public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } public string Rating { get; set; } }
使用菜单命令生成>生成 Movie或按下 Ctrl-Shift-B 生成应用程序。
现在,您已经更新了Model
类,你还需要更新\Views\Movies\Index.cshtml和\Views\Movies\Create.cshtml视图模板,以便在浏览器视图中显示新的Rating
属性。
打开\Views\Movies\Index.cshtml文件并添加<th>Rating</th>
只是后价格列的列标题。然后添加一个<td>
列附近的模板以呈现@item.Rating
值。下面是更新的Index.cshtml视图模板的样子:
@model IEnumerable<MvcMovie.Models.Movie> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table> <tr> <th> @Html.DisplayNameFor(model => model.Title) </th> <th> @Html.DisplayNameFor(model => model.ReleaseDate) </th> <th> @Html.DisplayNameFor(model => model.Genre) </th> <th> @Html.DisplayNameFor(model => model.Price) </th> <th> @Html.DisplayNameFor(model => model.Rating) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.ReleaseDate) </td> <td> @Html.DisplayFor(modelItem => item.Genre) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Rating) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", new { id=item.ID }) | @Html.ActionLink("Delete", "Delete", new { id=item.ID }) </td> </tr> } </table>
下一步,打开\Views\Movies\Create.cshtml文件,添加以下标记附近的形式结束。这样一部新电影在创建时,可以指定评级,这呈现一个文本框。
<div class="editor-label"> @Html.LabelFor(model => model.Rating) </div> <div class="editor-field"> @Html.EditorFor(model => model.Rating) @Html.ValidationMessageFor(model => model.Rating) </div>
现在,您已经更新的应用程序代码以支持新的Rating
属性。
现在运行该应用程序并导航到/Movies的 URL。当您这样做时,不过,您会看到以下错误之一:
你看到此错误因为在应用程序中的最新的Movie
模型类现在是Movie
的现有的数据库表的架构不同。(数据库表中没有Rating
列。)
有几种方法解决该错误:
- 有实体框架会自动删除并重新创建基于新模型类架构的数据库。这种做法是非常方便,做一个测试数据库 ; 积极发展时它允许您快速演变的模型和数据库的架构在一起。不利的方面,不过,是你失去现有数据库中的数据 — — 所以你别想在生产数据库上使用这种方法 !使用一个初始值设定项来自动种子具有测试数据的数据库通常是一种有效的方式来开发应用程序。实体框架数据库初始值设定项的详细信息,请参阅汤姆戴克ASP.NET MVC/实体框架教程.
- 显式修改现有数据库的架构,使其匹配模式的类。这种方法的优点是您保持您的数据。您可以进行此更改,要么手动或通过创建一个数据库更改脚本。
- 使用代码第一次迁移来更新数据库架构。
在本教程中,我们将使用代码第一次迁移。
更新的种子方法,以便它,为新的列提供值。打开 Migrations\Configuration.cs 文件,并将评级的字段添加到影片的每个对象。
new Movie { Title = "When Harry Met Sally", ReleaseDate = DateTime.Parse("1989-1-11"), Genre = "Romantic Comedy", Rating = "G", Price = 7.99M },
生成解决方案,然后打开软件包管理器控制台窗口,并输入下面的命令:
add-migration AddRatingMig
add-migration
命令告诉迁移框架来检查当前电影模型与当前的电影 DB 架构并创建必要的代码以将数据库迁移到新的模型。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"); } }
生成解决方案,然后在程序包管理器控制台窗口中输入"更新数据库"命令。
下面的图像显示的输出在程序包管理器控制台窗口中 (前面加 AddRatingMig 的日期戳将不同)。
重新运行应用程序,然后定位到 /Movies 的 URL。您可以看到新的评级字段。
单击创建新的链接来添加一部新电影。请注意您可以添加评级。
单击创建。新的电影,包括评级,现在显示在电影清单中:
您还应该向编辑、 细节和 SearchIndex 查看模板添加Rating
字段。
您可以再次在程序包管理器控制台窗口中输入"更新数据库"命令,将会进行任何更改,因为该架构匹配模型。
==============================翻译==============================