生成 Blazor 电影数据库应用(第 7 部分 - 添加新字段)

注意

此版本不是本文的最新版本。 有关当前版本,请参阅本文.NET 9 版本。

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

有关当前版本,请参阅本文.NET 9 版本。

本文是 Blazor 电影数据库应用教程的第七部分,介绍有关如何生成具有管理电影数据库功能的 ASP.NET Core Blazor Web App 的基础知识。

本教程系列的这一部分介绍如何向电影类、CRUD 页面和数据库添加新字段。

数据库更新由 EF Core 迁移处理。 EF Core 以透明方式跟踪对迁移历史记录表中数据库的更改,如果应用的模型类未与数据库的表和列同步,则会自动引发异常。 EF Core 迁移可快速排查数据库一致性问题。

重要

确认应用未在后续步骤中运行。

向应用模型添加分级

打开 Models/Movie.cs 文件,并添加一个 Rating 正则表达式的属性,该正则表达式将 Rating 值限制为确切的电影协会电影分级指定:

[Required]
[RegularExpression(@"^(G|PG|PG-13|R|NC-17)$")]
public string? Rating { get; set; }

将电影分级添加到应用的 CRUD 组件

打开 Create 组件定义文件 (Components/Pages/MoviePages/Create.razor)。

Price<div> 块和创建按钮 (<button>) 之间添加以下 <div> 块:

<div class="mb-3">
    <label for="rating" class="form-label">Rating:</label> 
    <InputText id="rating" @bind-Value="Movie.Rating" class="form-control" /> 
    <ValidationMessage For="() => Movie.Rating" class="text-danger" /> 
</div>

打开 Delete 组件定义文件 (Components/Pages/MoviePages/Delete.razor)。

Price 描述列表块和 EditForm 组件之间添加以下说明列表 (<dl>) 块:

<dl class="row">
    <dt class="col-sm-2">Rating</dt>
    <dd class="col-sm-10">@movie.Rating</dd>
</dl>

打开 Details 组件定义文件 (Components/Pages/MoviePages/Details.razor)。

Price 术语和元素后面添加以下说明列表术语 (<dt>) 和说明列表元素 (<dl>) 到结束的 </dl> 标记内:

<dt class="col-sm-2">Rating</dt>
<dd class="col-sm-10">@movie.Rating</dd>

打开 Edit 组件定义文件 (Components/Pages/MoviePages/Edit.razor)。

Price<div> 块和保存按钮 (<button>) 之间添加以下 <div> 块:

<div class="mb-3">
    <label for="rating" class="form-label">Rating:</label>
    <InputText id="rating" @bind-Value="Movie.Rating" class="form-control" />
    <ValidationMessage For="() => Movie.Rating" class="text-danger" />
</div>

打开 Index 组件定义文件 (Components/Pages/MoviePages/Index.razor)。

更新 QuickGrid 组件以包含电影分级。 在 Price 的列之后立即添加以下 PropertyColumn<TGridItem,TProp>

<PropertyColumn Property="movie => movie.Rating" />

更新 SeedData 类 (Data/SeedData.cs) 以提供用于重新种子设定操作的新 Rating 属性的默认值。

以下更改适用于 Mad Maxnew Movie 块。 将 Rating = "R", 添加到块中:

new Movie
{
    Title = "Mad Max",
    ReleaseDate = DateOnly.Parse("1979-4-12"),
    Genre = "Sci-fi (Cyberpunk)",
    Price = 2.51M,
+   Rating = "R",
},

以相同方式将 Rating 属性添加到其他每个 new Movie 块。 以下是添加新 Rating 行时剩余 Mad Max 电影的分级:

  • The Road Warrior:R
  • Mad Max: Beyond Thunderdome:PG-13
  • Mad Max: Fury Road:R
  • Furiosa: A Mad Max Saga:R

保存所有更新的文件。

目前请勿运行应用。 生成应用以确认没有任何错误。

从菜单栏中,选择“生成”>“重新生成解决方案”。

在“命令面板”中使用 .NET: Build 命令。

在打开到项目的根文件夹的命令行界面中,执行以下命令:

dotnet build

在继续执行下一步之前,请修复应用中通过粘贴上述标记和代码引入的任何错误。

更新数据库

如果此时尝试运行应用,应用将失败并出现 SQL 异常,因为数据库在其 Movie 表中不包含 Rating 列。 可以通过三种方法来解决数据库架构与模型架构之间的差异:

  • 修改数据库的架构,使它与模型类匹配。 此方法的优点是它维护数据库的数据。 使用数据库工具或创建数据库更改脚本采用此方法,这是本教程未涵盖但可以使用其他文章学习的方法。 此方法的缺点是,需要更多的时间,并且更容易出错,因为其复杂性增加。 本教程不采用此方法。
  • 使用 EF Core 自动删除并使用新的模型类架构重新创建数据库,在此过程中丢失存储在数据库中的数据。 在运行应用时,数据库会使用新数据重新设定种子。 通过该方法可以一起快速改进模型和数据库架构。 不要对必须保留数据的生产数据库使用此方法。 本教程不采用此方法。
  • 在应用中更改模型后使用 EF Core 迁移来更新数据库架构。 此方法高效,并保留数据库的数据。 本教程采用此方法。

创建迁移并更新数据库的架构。 电影分级作为 Rating 列添加到数据库的 Movie 表中。

在 Visual Studio 解决方案资源管理器中,双击“连接的服务”。 在“服务依赖项”的“SQL Server Express LocalDB”区域中,选择省略号 (...),然后选择“添加迁移”。

为迁移提供描述迁移的迁移名称,例如,AddRatingField。 等待数据库上下文加载到“DbContext 类名”字段。 选择“完成”以创建迁移。 操作完成后,选择“关闭”。

迁移:

  • Movie 模型与 Movie 数据库表架构进行比较。
  • 创建代码以迁移数据库架构,使其与模型匹配。

创建迁移不会在更新数据库时自动为分级预配默认值。 但是,可以手动更改迁移文件以应用默认电影分级值,这在需要默认值的许多记录时非常有用。 在这种情况下,除了一部电影外,所有 Mad Max 电影分级都为 R,因此,Rating 列的默认值为“R”是适当的选择。 一部没有 R 分级的电影稍后可以在正在运行的应用中更新。

在 Visual Studio 解决方案资源管理器中,检查项目 Migrations 文件夹中的文件。 打开添加电影分级字段的迁移文件,该字段具有文件名 {TIME STAMP}_AddRatingField.cs,其中 {TIME STAMP} 占位符是时间戳(例如,20240530123755_AddRatingField.cs)。

查找将分级列添加到数据库中 Movie 表的 AddColumn 块。 修改应用默认值 (defaultValue) 的最后一行。 将它从空字符串 ("") 更改为 R 电影分级 ("R"):

migrationBuilder.AddColumn<string>(
    name: "Rating",
    table: "Movie",
    type: "nvarchar(max)",
    nullable: false,
-   defaultValue: "");
+   defaultValue: "R");

保存迁移文件。

在“服务依赖项”的“SQL Server Express LocalDB”区域中,再次选择省略号 (...),然后选择“更新数据库”命令。

此时会打开“使用最新迁移更新数据库”对话框。 等待“DbContext 类名”字段更新,并加载之前的迁移。 选择“完成”按钮。 操作完成后,选择“关闭”按钮。

修改一部未分级为 R 的电影:

  1. 运行应用。
  2. 编辑 Mad Max: Beyond Thunderdome 电影。
  3. 将电影分级从 R 更新为 PG-13。 保存更改。

注意

修改迁移文件的替代方法是删除数据库中的记录,然后重新运行应用以为数据库重新设定种子。 种子设定代码之前已修改,以提供默认值。 如果在种子设定过程中使用 C# 代码更好地控制或更快地实现字段的默认值分配,则这种方法非常有用。 有关详细信息,请参阅本文末尾的“删除所有数据库记录并为数据库重新设定种子”部分。

在“终端”(“终端”菜单>“新建终端”)中,执行以下命令以添加迁移。 迁移名称 (AddRatingField) 是迁移的任意说明:

dotnet ef migrations add AddRatingField

dotnet-ef migrations 命令:

  • Movie 模型与 Movie 数据库表架构进行比较。
  • 创建代码以迁移数据库架构,使其与模型匹配。

创建迁移不会在更新数据库时自动为分级预配默认值。 但是,可以手动对迁移文件进行少量更改,以应用默认电影分级值,这在需要默认值的许多记录时非常有用。 在这种情况下,除了一部电影外,所有 Mad Max 电影分级都为 R,因此,Rating 列的默认值为“R”是合适的。 一部没有 R 分级的电影稍后可以在正在运行的应用中更新。

检查项目 Migrations 文件夹中的文件。 打开添加电影分级字段的迁移文件,该字段具有文件名 {TIME STAMP}_AddRatingField.cs,其中 {TIME STAMP} 占位符是时间戳(例如,20240530123755_AddRatingField.cs)。

查找将分级列添加到数据库中 Movie 表的 AddColumn 块。 修改应用默认值 (defaultValue) 的最后一行。 将它从空字符串 ("") 更改为 R 电影分级 ("R"):

migrationBuilder.AddColumn<string>(
    name: "Rating",
    table: "Movie",
    type: "nvarchar(max)",
    nullable: false,
-   defaultValue: "");
+   defaultValue: "R");

保存迁移文件。

在“终端”中,执行以下命令来更新数据库,该数据库在添加带默认值的电影分级列时会保留现有数据:

dotnet ef database update

修改一部未分级为 R 的电影:

  1. 运行应用。
  2. 编辑 Mad Max: Beyond Thunderdome 电影。
  3. 将电影分级从 R 更新为 PG-13。 保存更改。

注意

修改迁移文件的替代方法是删除数据库中的记录,然后重新运行应用以为数据库重新设定种子。 种子设定代码之前已修改,以提供默认值。 如果在种子设定过程中使用 C# 代码更好地控制或更快地将默认值分配给字段,则这种方法非常有用。 有关详细信息,请参阅本文末尾的“删除所有数据库记录并为数据库重新设定种子”部分。

在打开到项目的根文件夹的命令行界面中,执行以下命令以添加迁移。 迁移名称 (AddRatingField) 是迁移的任意说明:

dotnet ef migrations add AddRatingField

dotnet-ef migrations 命令:

  • Movie 模型与 Movie 数据库表架构进行比较。
  • 创建代码以迁移数据库架构,使其与模型匹配。

创建迁移不会在更新数据库时自动为分级预配默认值。 但是,可以手动对迁移文件进行少量更改,以应用默认电影分级值,这在需要默认值的许多记录时非常有用。 在这种情况下,除了一部电影外,所有 Mad Max 电影分级都为 R,因此,Rating 列的默认值为“R”是合适的。 一部没有 R 分级的电影稍后可以在正在运行的应用中更新。

检查项目 Migrations 文件夹中的文件。 打开添加电影分级字段的迁移文件,该字段具有文件名 {TIME STAMP}_AddRatingField.cs,其中 {TIME STAMP} 占位符是时间戳(例如,20240530123755_AddRatingField.cs)。

查找将分级列添加到数据库中 Movie 表的 AddColumn 块。 修改应用默认值 (defaultValue) 的最后一行。 将它从空字符串 ("") 更改为 R 电影分级 ("R"):

migrationBuilder.AddColumn<string>(
    name: "Rating",
    table: "Movie",
    type: "nvarchar(max)",
    nullable: false,
-   defaultValue: "");
+   defaultValue: "R");

保存迁移文件。

执行以下命令来更新数据库,该数据库在添加具有默认值的电影分级列时会保留现有数据:

dotnet ef database update

修改一部未分级为 R 的电影:

  1. 运行应用。
  2. 编辑 Mad Max: Beyond Thunderdome 电影。
  3. 将电影分级从 R 更新为 PG-13。 保存更改。

注意

修改迁移文件的替代方法是删除数据库中的记录,然后重新运行应用以为数据库重新设定种子。 种子设定代码之前已修改,以提供默认值。 如果在种子设定过程中使用 C# 代码更好地控制或更快地将默认值分配给字段,则这种方法非常有用。 有关详细信息,请参阅本文末尾的“删除所有数据库记录并为数据库重新设定种子”部分。

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

疑难解答

如果数据库损坏,请删除数据库并使用迁移重新创建数据库:

  1. SQL Server 对象资源管理器(SSOX) 选择数据库。
  2. 右键单击数据库,并选择“删除”。 请确保在列表中选择正确的数据库。
  3. 检查“关闭现有连接”。
  4. 选择“确定”
  5. 解决方案资源管理器中,双击“连接的服务”。 在“服务依赖项”区域中,选择省略号 (...),然后选择 SQL Server Express LocalDB区域中的“更新数据库”。 更新数据库将执行重新创建数据库的现有迁移。
  1. 删除数据库。 如果数据库工具与数据库建立连接,请先关闭工具,或使用该工具的功能关闭数据库连接并删除数据库。 请参阅工具的文档以获取指导。 请确保在列表中选择正确的数据库。

  2. 在“终端”(“终端”菜单>“新建终端”)中,执行以下命令以运行重新创建数据库的现有迁移:

    dotnet ef database update
    
  1. 删除数据库。 如果数据库工具与数据库建立连接,请先关闭工具,或使用该工具的功能关闭数据库连接并删除数据库。 请参阅工具的文档以获取指导。 请确保在列表中选择正确的数据库。

  2. 在打开到项目的根文件夹的命令行界面中,执行以下命令以运行重新创建数据库的现有迁移:

    dotnet ef database update
    

删除所有数据库记录并为数据库重新设定种子

本部分介绍使用新模型属性的默认值更新数据库的替代过程,而无需修改迁移文件。 如果遵循本文前面“更新数据库”部分中的所有步骤,则不需要遵循本部分中的指南。

若要删除数据库中的所有记录,请使用以下方法之一:

  • 运行应用并使用浏览器中的删除链接。 如果只有少数记录要删除,此方法的速度相当快。
  • 在 Visual Studio 中使用SQL Server 对象资源管理器 (SSOX),删除数据库记录。 当数据库表可见时,右键单击该表并选择“查看数据”。 当表格打开以显示电影记录时,请选择第一条记录。 按住 Shift 键并选择最后一条记录以选择表中的所有记录。 选中所有记录后,按“删除”键删除记录。 如果要删除许多记录,此方法的速度相当快。
  • 在 SSOX 的 Visual Studio 中,右键单击数据库并选择“新建查询”。 会打开一个空白文件 (.sql)。 将以下命令粘贴到文件中:DELETE FROM dbo.Movie;。 选择绿色的“执行”三角形以执行查询或按键盘上的 Ctrl+Shift+E。 在“消息”选项卡中,SSOX 会报告受查询影响(在此例中为删除)的行数。 如果愿意,可以保存查询供以后使用。 否则,请关闭文件而无需保存。 当表很大且包含数百到数千条记录时,此方法特别有用。
  • 运行应用并使用浏览器中的删除链接。 如果只有少数记录要删除,此方法的速度相当快。
  • 使用数据库工具†,删除数据库记录。 在允许直接操作数据的大多数数据库工具中,在工具中打开数据库表的数据视图。 当表格打开以显示电影记录时,请选择第一条记录。 按住 Shift 键并选择最后一条记录以选择数据库中的所有记录。 选中所有记录后,按“删除”键删除记录。 可能需要根据正在使用的数据库工具调整这些说明。 有关详细信息,请参阅工具的文档。 如果要删除许多记录,此方法的速度相当快。
  • 使用数据库工具†,对电影表执行 SQL 查询以删除表的记录。 SQL 命令是 DELETE FROM dbo.Movie;。 如果愿意,可以保存查询供以后使用。 否则,请关闭文件而无需保存。 有关确切步骤,请参阅工具的文档。 当表很大且包含数百到数千条记录时,此方法特别有用。

数据库工具:开放市场上有许多可用于 SQL 数据库的免费和零售数据库工具。 请参阅 Internet 资源以查找适合的数据库和平台的资源。

  • 运行应用并使用浏览器中的删除链接。 如果只有少数记录要删除,此方法的速度相当快。
  • 使用数据库工具†,删除数据库记录。 在允许直接操作数据的大多数数据库工具中,在工具中打开数据库表的数据视图。 当表格打开以显示电影记录时,请选择第一条记录。 按住 Shift 键并选择最后一条记录以选择数据库中的所有记录。 选中所有记录后,按“删除”键删除记录。 可能需要根据正在使用的数据库工具调整这些说明。 有关详细信息,请参阅工具的文档。 如果要删除许多记录,此方法的速度相当快。
  • 使用数据库工具†,对电影表执行 SQL 查询以删除表的记录。 SQL 命令是 DELETE FROM dbo.Movie;。 如果愿意,可以保存查询供以后使用。 否则,请关闭文件而无需保存。 有关确切步骤,请参阅工具的文档。 当表很大且包含数百到数千条记录时,此方法特别有用。

数据库工具:开放市场上有许多可用于 SQL 数据库的免费和零售数据库工具。 请参阅 Internet 资源以查找适合的数据库和平台的资源。

注意

从数据库中删除记录时,请格外小心。 删除记录是永久性的,无需执行额外的数据丢失缓解步骤。 生产数据库通常预配数据的自动备份副本,无论是即时修改数据库还是定期备份副本,包括异地副本和永久物理存储数据。

删除所有记录后,运行应用。 初始值设定项重新设定数据库并包含基于种子设定代码的 Rating 字段的正确电影分级。

用完成的示例排除故障

如果在学习本教程时遇到无法从文本中解决的问题,请将代码与 Blazor 示例存储库中已完成的项目进行比较:

Blazor 示例 GitHub 存储库 (dotnet/blazor-samples)

选择最新版本文件夹。 本教程项目的示例文件夹命名为 BlazorWebAppMovies

其他资源

Mad MaxThe Road WarriorMad Max: Beyond ThunderdomeMad Max: Fury RoadFuriosa: A Mad Max SagaWarner Bros. Entertainment 的商标和版权。

后续步骤