将新字段添加到 ASP.NET Core 中的 Razor 页面Add a new field to a Razor Page in ASP.NET Core

本文内容

作者:Rick Anderson

查看或下载示例代码如何下载)。

查看或下载示例代码如何下载)。

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

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

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

  • 向数据库添加 __EFMigrationsHistory 表格,以跟踪数据库的架构是否与从生成它的模型类同步。
  • 如果该模型类未与数据库同步,EF 将引发异常。

通过自动验证同步的架构/模型可以更容易地发现不一致的数据库/代码问题。

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

打开 Models/Movie.cs 文件,并添加 Rating 属性:

  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. }

构建应用程序。

编辑 Pages/Movies/Index.cshtml,并添加 Rating 字段:

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <form>
  11. <p>
  12. <select asp-for="MovieGenre" asp-items="Model.Genres">
  13. <option value="">All</option>
  14. </select>
  15. Title: <input type="text" asp-for="SearchString" />
  16. <input type="submit" value="Filter" />
  17. </p>
  18. </form>
  19. <table class="table">
  20. <thead>
  21. <tr>
  22. <th>
  23. @Html.DisplayNameFor(model => model.Movie[0].Title)
  24. </th>
  25. <th>
  26. @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
  27. </th>
  28. <th>
  29. @Html.DisplayNameFor(model => model.Movie[0].Genre)
  30. </th>
  31. <th>
  32. @Html.DisplayNameFor(model => model.Movie[0].Price)
  33. </th>
  34. <th>
  35. @Html.DisplayNameFor(model => model.Movie[0].Rating)
  36. </th>
  37. <th></th>
  38. </tr>
  39. </thead>
  40. <tbody>
  41. @foreach (var item in Model.Movie)
  42. {
  43. <tr>
  44. <td>
  45. @Html.DisplayFor(modelItem => item.Title)
  46. </td>
  47. <td>
  48. @Html.DisplayFor(modelItem => item.ReleaseDate)
  49. </td>
  50. <td>
  51. @Html.DisplayFor(modelItem => item.Genre)
  52. </td>
  53. <td>
  54. @Html.DisplayFor(modelItem => item.Price)
  55. </td>
  56. <td>
  57. @Html.DisplayFor(modelItem => item.Rating)
  58. </td>
  59. <td>
  60. <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
  61. <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
  62. <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
  63. </td>
  64. </tr>
  65. }
  66. </tbody>
  67. </table>

更新以下页面:

  • Rating 字段添加到“删除”和“详细信息”页面。
  • 使用 Rating 字段更新 Create.cshtml
  • Rating 字段添加到“编辑”页面。

在 DB 更新为包括新字段之前,应用将不会正常工作。在不更新数据库的情况下运行应用会引发 SqlException

SqlException: Invalid column name 'Rating'.

SqlException 异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。(数据库表中没有 Rating 列。)

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

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

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

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

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

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

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

请参阅已完成的 SeedData.cs 文件

生成解决方案。

添加用于评级字段的迁移Add a migration for the rating field

从“工具”菜单中,选择“NuGet 包管理器”>“包管理器控制台”。 在 PMC 中,输入以下命令:

  1. Add-Migration Rating
  2. Update-Database

Add-Migration 命令会通知框架执行以下操作:

  • Movie 模型与 Movie DB 架构进行比较。
  • 创建代码以将 DB 架构迁移到新模型。

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

Update-Database 命令指示框架将架构更改应用到数据库并保留现有数据。

如果删除 DB 中的所有记录,种子初始值设定项会设定 DB 种子,并将包括 Rating 字段。可以使用浏览器中的删除链接,也可以从 Sql Server 对象资源管理器 (SSOX) 执行此操作。

另一个方案是删除数据库,并使用迁移来重新创建该数据库。删除 SSOX 中的数据库:

  • 在 SSOX 中选择数据库。

  • 右键单击数据库,并选择“删除”。

  • 检查“关闭现有连接” 。

  • 选择“确定” 。

  • PMC 中更新数据库:

  1. Update-Database

删除并重新创建数据库Drop and re-create the database

备注

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

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

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

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

删除迁移文件夹。使用以下命令重新创建数据库。

  1. dotnet ef database drop
  2. dotnet ef migrations add InitialCreate
  3. dotnet ef database update

运行应用,并验证是否可以创建/编辑/显示具有 Rating 字段的电影。如果数据库未设定种子,则在 SeedData.Initialize 方法中设置断点。

其他资源Additional resources

上一篇:添加搜索下一篇:添加验证

查看或下载示例代码如何下载)。

查看或下载示例代码如何下载)。

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

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

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

  • 向数据库添加表格,以跟踪数据库的架构是否与从生成它的模型类同步。
  • 如果该模型类未与数据库同步,EF 将引发异常。

通过自动验证同步的架构/模型可以更容易地发现不一致的数据库/代码问题。

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

打开 Models/Movie.cs 文件,并添加 Rating 属性:

  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. }

构建应用程序。

编辑 Pages/Movies/Index.cshtml,并添加 Rating 字段:

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <form>
  11. <p>
  12. <select asp-for="MovieGenre" asp-items="Model.Genres">
  13. <option value="">All</option>
  14. </select>
  15. Title: <input type="text" asp-for="SearchString" />
  16. <input type="submit" value="Filter" />
  17. </p>
  18. </form>
  19. <table class="table">
  20. <thead>
  21. <tr>
  22. <th>
  23. @Html.DisplayNameFor(model => model.Movie[0].Title)
  24. </th>
  25. <th>
  26. @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
  27. </th>
  28. <th>
  29. @Html.DisplayNameFor(model => model.Movie[0].Genre)
  30. </th>
  31. <th>
  32. @Html.DisplayNameFor(model => model.Movie[0].Price)
  33. </th>
  34. <th>
  35. @Html.DisplayNameFor(model => model.Movie[0].Rating)
  36. </th>
  37. <th></th>
  38. </tr>
  39. </thead>
  40. <tbody>
  41. @foreach (var item in Model.Movie)
  42. {
  43. <tr><td>
  44. @Html.DisplayFor(modelItem => item.Title)
  45. </td>
  46. <td>
  47. @Html.DisplayFor(modelItem => item.ReleaseDate)
  48. </td>
  49. <td>
  50. @Html.DisplayFor(modelItem => item.Genre)
  51. </td>
  52. <td>
  53. @Html.DisplayFor(modelItem => item.Price)
  54. </td>
  55. <td>
  56. @Html.DisplayFor(modelItem => item.Rating)
  57. </td>
  58. <td>
  59. <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
  60. <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
  61. <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
  62. </td>
  63. </tr>
  64. }
  65. </tbody>
  66. </table>

更新以下页面:

  • Rating 字段添加到“删除”和“详细信息”页面。
  • 使用 Rating 字段更新 Create.cshtml
  • Rating 字段添加到“编辑”页面。

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

SqlException: Invalid column name 'Rating'.

此错误是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。(数据库表中没有 Rating 列。)

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

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

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

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

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

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

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

请参阅已完成的 SeedData.cs 文件

生成解决方案。

添加用于评级字段的迁移Add a migration for the rating field

从“工具”菜单中,选择“NuGet 包管理器”>“包管理器控制台”。 在 PMC 中,输入以下命令:

  1. Add-Migration Rating
  2. Update-Database

Add-Migration 命令会通知框架执行以下操作:

  • Movie 模型与 Movie DB 架构进行比较。
  • 创建代码以将 DB 架构迁移到新模型。

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

Update-Database 命令指示框架将架构更改应用到数据库。

如果删除 DB 中的所有记录,种子初始值设定项会设定 DB 种子,并将包括 Rating 字段。可以使用浏览器中的删除链接,也可以从 Sql Server 对象资源管理器 (SSOX) 执行此操作。

另一个方案是删除数据库,并使用迁移来重新创建该数据库。删除 SSOX 中的数据库:

  • 在 SSOX 中选择数据库。

  • 右键单击数据库,并选择“删除”。

  • 检查“关闭现有连接” 。

  • 选择“确定” 。

  • PMC 中更新数据库:

  1. Update-Database

删除并重新创建数据库Drop and re-create the database

备注

在本教程中,使用 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 字段的电影。如果数据库未设定种子,则在 SeedData.Initialize 方法中设置断点。

其他资源Additional resources

上一篇:添加搜索下一篇:添加验证