在这一节中,您将使用实体框架代码第一次迁移,迁移到模型类的一些变化,所以该更改应用于数据库。
默认情况下,当您使用实体框架代码优先将自动创建一个数据库,像你那样早些时候在本教程中,代码第一次添加一个表格到数据库,以帮助跟踪数据库的架构是否与它从生成的模型类同步。如果他们不同步,实体框架将引发错误。这使得更容易地在开发时可能发现否则只 (通过模糊错误) 在运行时跟踪问题。
设置代码第一次迁移模型更改
如果您使用的 Visual Studio 2012,双击解决方案资源管理器打开数据库工具中的Movies.mdf文件。Visual Studio 速成网站将显示数据库资源管理器中,Visual Studio 2012 将显示服务器资源管理器。如果您使用的 Visual Studio 2010,使用 SQL 服务器对象资源管理器。
在数据库 (数据库资源管理器、 服务器资源管理器或 SQL 服务器对象资源管理器) 工具中,在MovieDBContext
上右键单击并选择删除来删除电影数据库。
向后定位到解决方案资源管理器。Movies.mdf文件上点击鼠标右键并选择删除来删除电影数据库。
生成该应用程序,以确保没有错误。
从工具菜单上,单击库程序包管理器,然后程序包管理器控制台.
在程序包管理器控制台窗口中 PM>
提示符下输入"Enable-Migrations ContextTypeName MvcMovie.Models.MovieDBContext"。
启用迁移命令 (如上所示) 创建新的迁移文件夹中的Configuration.cs文件。
Visual Studio 会打开Configuration.cs文件。用以下代码替换Seed
方法在Configuration.cs文件中:
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"的名称是任意的和用于创建的迁移文件的名称。
代码第一次迁移的迁移文件夹中创建另一个类文件 (具有名称{DateStamp}_Initial.cs ),并且此类包含创建数据库架构的代码。迁移文件名前固定与时间戳以帮助订购。检查{DateStamp}_Initial.cs文件,它包含为电影 DB 创建电影表的说明。当您更新在下面,这说明数据库{DateStamp}_Initial.cs文件将运行并创建数据库架构。然后种子方法将运行来填充与试验数据 DB。
在程序包管理器控制台中,输入命令"update-database"来创建数据库并运行种子方法。
如果你得到一个错误,指示表已经存在并且无法创建,它可能是因为您运行应用程序,您已删除的数据库后,在您执行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; } }
生成应用程序的构建>建立电影菜单命令或按 CTRL-B 转变。
现在,您已经更新了Model
课,你还需要更新的\Views\Movies\Index.cshtml和\Views\Movies\Create.cshtml的视图模板,以在浏览器视图中显示新的Rating
属性。
打开\Views\Movies\Index.cshtml文件并添加 <th>Rating</th>
刚Price列的列标题。然后添加一个<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"); } }
生成解决方案,然后在程序包管理器控制台窗口中输入"update-database"命令。
下面的图像显示的输出在程序包管理器控制台窗口中 (预先计算 AddRatingMig 的日期戳将不同)。
重新运行应用程序,然后定位到 /Movies URL。你可以看到新的评级领域。
单击创建新的链接以添加一部新电影。请注意您可以添加一个评级。
单击创建。新的电影,包括评级,显示现在电影清单:
此外应将Rating
字段添加到编辑、 细节和 SearchIndex 的视图模板。
您可以再次在程序包管理器控制台窗口中输入"更新数据库"命令,将进行任何更改,因为该架构匹配模型。
在本节,您看到了如何可以修改模型对象和保持数据库的同步所做的更改。您还学习了的方式来填充新创建的数据库,使用示例数据,所以你可以试试方案。接下来,让我们看看如何可以将富裕的验证逻辑添加到模型的类和启用一些业务规则来强制执行。