将新字段添加到 ASP.NET Core MVC 应用Add a new field to an ASP.NET Core MVC app

本文内容

作者:Rick Anderson

在此部分中,Entity Framework Code First 迁移用于:

  • 将新字段添加到模型。
  • 将新字段迁移到数据库。

使用 EF Code First 自动创建数据库时,Code First 将:

  • 将表添加到数据库,以跟踪数据库的架构。
  • 验证数据库与生成它的模型类是否同步。如果它们不同步,EF 则会引发异常。这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性Add a Rating Property to the Movie Model

Rating 属性添加到 Models/Movie.cs :

  1. public class Movie
  2. {
  3. public int Id { get; set; }
  4. public string Title { get; set; }
  5. [Display(Name = "Release Date")]
  6. [DataType(DataType.Date)]
  7. public DateTime ReleaseDate { get; set; }
  8. public string Genre { get; set; }
  9. [Column(TypeName = "decimal(18, 2)")]
  10. public decimal Price { get; set; }
  11. public string Rating { get; set; }
  12. }

生成应用

Ctrl+Shift+B

  1. dotnet build

命令 ⌘ + B

因为已经添加新字段到 Movie 类,所以需要更新绑定允许名单,将此新属性纳入其中。在 MoviesController.cs 中,更新 CreateEdit 操作方法的 [Bind] 属性,以包括 Rating 属性:

  1. [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段 :

  1. <thead>
  2. <tr>
  3. <th>
  4. @Html.DisplayNameFor(model => model.Movies[0].Title)
  5. </th>
  6. <th>
  7. @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
  8. </th>
  9. <th>
  10. @Html.DisplayNameFor(model => model.Movies[0].Genre)
  11. </th>
  12. <th>
  13. @Html.DisplayNameFor(model => model.Movies[0].Price)
  14. </th>
  15. <th>
  16. @Html.DisplayNameFor(model => model.Movies[0].Rating)
  17. </th>
  18. <th></th>
  19. </tr>
  20. </thead>
  21. <tbody>
  22. @foreach (var item in Model.Movies)
  23. {
  24. <tr>
  25. <td>
  26. @Html.DisplayFor(modelItem => item.Title)
  27. </td>
  28. <td>
  29. @Html.DisplayFor(modelItem => item.ReleaseDate)
  30. </td>
  31. <td>
  32. @Html.DisplayFor(modelItem => item.Genre)
  33. </td>
  34. <td>
  35. @Html.DisplayFor(modelItem => item.Price)
  36. </td>
  37. <td>
  38. @Html.DisplayFor(modelItem => item.Rating)
  39. </td>
  40. <td>
  41. <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |

使用 Rating 字段更新 /Views/Movies/Create.cshtml 。

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。IntelliSense 适用于标记帮助程序

开发人员已在视图的第二个标签元素中键入字母 R 用作 asp-for 的特性值。

更新剩余模板。

更新 SeedData 类,使它提供新列的值。示例更改如下所示,但可能需要对每个 new Movie 做出此更改。

  1. new Movie
  2. {
  3. Title = "When Harry Met Sally",
  4. ReleaseDate = DateTime.Parse("1989-1-11"),
  5. Genre = "Romantic Comedy",
  6. Rating = "R",
  7. Price = 7.99M
  8. },

在 DB 更新为包括新字段之前,应用将不会正常工作。如果它现在运行,将引发以下 SqlException

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。(数据库表中没有 Rating 列。)

可通过几种方法解决此错误:

  • 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法!使用初始值设定项,以使用测试数据自动设定数据库种子,这通常是开发应用程序的有效方式。对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

  • 对现有数据库架构进行显式修改,使它与模型类相匹配。此方法的优点是可以保留数据。可以手动或通过创建数据库更改脚本进行此更改。

  • 使用 Code First 迁移更新数据库架构。

对于本教程,请使用 Code First 迁移。

从“工具”菜单中,选择“NuGet 包管理器”>“包管理器控制台”。

PMC 菜单

在 PMC 中,输入以下命令:

  1. Add-Migration Rating
  2. Update-Database

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

名称“Rating”是任意的,用于对迁移文件进行命名。为迁移文件使用有意义的名称是有帮助的。

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

备注

在本教程中,使用 Entity Framework Core 迁移功能(若可行)。迁移会更新数据库架构,使其与数据模型中的更改相匹配。但是,迁移仅能执行 EF Core 提供程序所支持的更改类型,且 SQLite 提供程序的功能将受限。例如,支持添加列,但不支持删除或更改列。如果已创建迁移以删除或更改列,则 ef migrations add 命令将成功,但 ef database update 命令会失败。由于上述限制,本教程不对 SQLite 架构更改使用迁移。转而在架构更改时,放弃并重新创建数据库。

要绕开 SQLite 限制,可手动写入迁移代码,在表内容更改时重新生成表。表重新生成涉及:

  • 创建新表。
  • 将旧表中的数据复制到新表中。
  • 放弃旧表。
  • 为新表重命名。

有关更多信息,请参见以下资源:

删除数据库并通过迁移重新创建数据库。若要删除该数据库,请删除数据库文件 (MvcMovie.db) 。然后运行 ef database update 命令:

  1. dotnet ef database update

运行应用,并验证是否可以创建、编辑和显示具有 Rating 字段的电影。更新应用:

  • EditDetailsDelete 视图模板添加 Rating 字段。
  • 更新 MoviesController 的编辑操作方法中的绑定。

上一页下一页