注意
此版本不是本文的最新版本。 有关当前版本,请参阅本文的 .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 的电影:
- 运行应用。
- 编辑 Mad Max: Beyond Thunderdome 电影。
- 将电影分级从
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 的电影:
- 运行应用。
- 编辑 Mad Max: Beyond Thunderdome 电影。
- 将电影分级从
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 的电影:
- 运行应用。
- 编辑 Mad Max: Beyond Thunderdome 电影。
- 将电影分级从
R
更新为PG-13
。 保存更改。
注意
修改迁移文件的替代方法是删除数据库中的记录,然后重新运行应用以为数据库重新设定种子。 种子设定代码之前已修改,以提供默认值。 如果在种子设定过程中使用 C# 代码更好地控制或更快地将默认值分配给字段,则这种方法非常有用。 有关详细信息,请参阅本文末尾的“删除所有数据库记录并为数据库重新设定种子”部分。
运行应用,并验证是否可以创建、编辑和显示具有新电影评级字段的电影。
疑难解答
如果数据库损坏,请删除数据库并使用迁移重新创建数据库:
- 在SQL Server 对象资源管理器(SSOX) 选择数据库。
- 右键单击数据库,并选择“删除”。 请确保在列表中选择正确的数据库。
- 检查“关闭现有连接”。
- 选择“确定”。
- 在解决方案资源管理器中,双击“连接的服务”。 在“服务依赖项”区域中,选择省略号 (
...
),然后选择 SQL Server Express LocalDB区域中的“更新数据库”。 更新数据库将执行重新创建数据库的现有迁移。
删除数据库。 如果数据库工具与数据库建立连接,请先关闭工具,或使用该工具的功能关闭数据库连接并删除数据库。 请参阅工具的文档以获取指导。 请确保在列表中选择正确的数据库。
在“终端”(“终端”菜单>“新建终端”)中,执行以下命令以运行重新创建数据库的现有迁移:
dotnet ef database update
删除数据库。 如果数据库工具与数据库建立连接,请先关闭工具,或使用该工具的功能关闭数据库连接并删除数据库。 请参阅工具的文档以获取指导。 请确保在列表中选择正确的数据库。
在打开到项目的根文件夹的命令行界面中,执行以下命令以运行重新创建数据库的现有迁移:
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
。
其他资源
Legal
Mad Max、The Road Warrior、Mad Max: Beyond Thunderdome、Mad Max: Fury Road 和 Furiosa: A Mad Max Saga 是 Warner Bros. Entertainment 的商标和版权。