文档
-
Razor 页面教程系列第 5 部分。
-
Razor 页面教程系列第 6 部分。
-
Razor 页面教程系列的第 4 部分。
备注
此版本不是本文的最新版本。 有关当前版本,请参阅本文的 .NET 9 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 有关当前版本,请参阅本文的 .NET 9 版本。
在本部分中 ,Entity Framework Core (EF Core) 用于根据应用的模型类定义数据库架构:
此方法 EF Core 允许更敏捷的开发过程。 开发人员直接处理应用的数据模型,数据库架构在创建后自动同步,开发人员无需在数据库管理工具中来回切换上下文。 有关 Entity Framework Core 及其优势的概述,请参阅 Entity Framework Core。
使用 EF Code 自动创建和跟踪数据库:
__EFMigrationsHistory
表格,以跟踪数据库的架构是否与从生成它的模型类同步。自动验证架构与模型是否同步可以更容易地发现不一致的数据库代码问题。
打开 Models/Movie.cs
文件并添加 Rating
属性:
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
public string Rating { get; set; } = string.Empty;
}
编辑 Pages/Movies/Index.cshtml
,并添加 Rating
字段:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie)
{
<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>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
使用 Rating
字段更新以下页面:
在数据库更新为包括新字段之前,应用将不会正常工作。 在不更新数据库的情况下运行应用会引发 SqlException
:
SqlException: Invalid column name 'Rating'.
SqlException
异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。 数据库表中没有 Rating
列。
可通过几种方法解决此错误:
对于本教程,请使用 EF Core 迁移。
更新 SeedData
类,使它提供新列的值。 示例更改如下所示,但对每个 new Movie
块做出此更改。
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M,
Rating = "R"
},
生成应用
按 Ctrl+Shift+B
从“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。
在包管理器控制台 (PMC) 中输入以下命令:
Add-Migration Rating
Add-Migration
命令会通知框架执行以下操作:
Movie
模型与 Movie
数据库架构进行比较。名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
在 PMC 中,输入以下命令:
Update-Database
Update-Database
命令指示框架将架构更改应用到数据库并保留现有数据。
删除数据库中的所有记录后,初始化表达式会设定数据库种子,并将包括 Rating
字段。 可以使用浏览器中的删除链接,也可从 SQL Server 对象资源管理器 (SSOX) 进行删除。
另一个方案是删除数据库,并使用迁移来重新创建该数据库。 删除 SSOX 中的数据库:
在 SSOX 中选择数据库。
右键单击数据库,并选择“删除”。
检查“关闭现有连接”。
选择“确定”。
在 PMC 中更新数据库:
Update-Database
运行应用,并验证是否可以创建、编辑和显示具有 Rating
字段的电影。 如果数据库未设定种子,则在 SeedData.Initialize
方法中设置断点。
在此部分中,Entity Framework Code First 迁移用于:
使用 EF Code First 自动创建和跟踪数据库时,Code First 将:
__EFMigrationsHistory
表格,以跟踪数据库的架构是否与从生成它的模型类同步。自动验证架构与模型是否同步可以更容易地发现不一致的数据库代码问题。
打开 Models/Movie.cs
文件并添加 Rating
属性:
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
public string Rating { get; set; } = string.Empty;
}
编辑 Pages/Movies/Index.cshtml
,并添加 Rating
字段:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie)
{
<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>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
使用 Rating
字段更新以下页面:
在数据库更新为包括新字段之前,应用将不会正常工作。 在不更新数据库的情况下运行应用会引发 SqlException
:
SqlException: Invalid column name 'Rating'.
SqlException
异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。 数据库表中没有 Rating
列。
可通过几种方法解决此错误:
对于本教程,请使用 Code First 迁移。
更新 SeedData
类,使它提供新列的值。 示例更改如下所示,但对每个 new Movie
块做出此更改。
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M,
Rating = "R"
},
生成应用
按 Ctrl+Shift+B
从“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。
在 PMC 中,输入以下命令:
Add-Migration Rating
Update-Database
Add-Migration
命令会通知框架执行以下操作:
Movie
模型与 Movie
数据库架构进行比较。名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
Update-Database
命令指示框架将架构更改应用到数据库并保留现有数据。
删除数据库中的所有记录后,初始化表达式会设定数据库种子,并将包括 Rating
字段。 可以使用浏览器中的删除链接,也可从 SQL Server 对象资源管理器 (SSOX) 进行删除。
另一个方案是删除数据库,并使用迁移来重新创建该数据库。 删除 SSOX 中的数据库:
在 SSOX 中选择数据库。
右键单击数据库,并选择“删除”。
检查“关闭现有连接”。
选择“确定”。
在 PMC 中更新数据库:
Update-Database
运行应用,并验证是否可以创建、编辑和显示具有 Rating
字段的电影。 如果数据库未设定种子,则在 SeedData.Initialize
方法中设置断点。
在此部分中,Entity Framework Code First 迁移用于:
使用 EF Code First 自动创建和跟踪数据库时,Code First 将:
__EFMigrationsHistory
表格,以跟踪数据库的架构是否与从生成它的模型类同步。自动验证架构与模型是否同步可以更容易地发现不一致的数据库代码问题。
打开 Models/Movie.cs
文件并添加 Rating
属性:
public class Movie
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
public string Rating { get; set; } = string.Empty;
}
编辑 Pages/Movies/Index.cshtml
,并添加 Rating
字段:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie)
{
<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>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
使用 Rating
字段更新以下页面:
在数据库更新为包括新字段之前,应用将不会正常工作。 在不更新数据库的情况下运行应用会引发 SqlException
:
SqlException: Invalid column name 'Rating'.
SqlException
异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。 数据库表中没有 Rating
列。
可通过几种方法解决此错误:
对于本教程,请使用 Code First 迁移。
更新 SeedData
类,使它提供新列的值。 示例更改如下所示,但对每个 new Movie
块做出此更改。
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M,
Rating = "R"
},
生成应用
按 Ctrl+Shift+B
从“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。
在 PMC 中,输入以下命令:
Add-Migration Rating
Update-Database
Add-Migration
命令会通知框架执行以下操作:
Movie
模型与 Movie
数据库架构进行比较。名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
Update-Database
命令指示框架将架构更改应用到数据库并保留现有数据。
删除数据库中的所有记录后,初始化表达式会设定数据库种子,并将包括 Rating
字段。 可以使用浏览器中的删除链接,也可从 SQL Server 对象资源管理器 (SSOX) 进行删除。
另一个方案是删除数据库,并使用迁移来重新创建该数据库。 删除 SSOX 中的数据库:
在 SSOX 中选择数据库。
右键单击数据库,并选择“删除”。
检查“关闭现有连接”。
选择“确定”。
在 PMC 中更新数据库:
Update-Database
运行应用,并验证是否可以创建、编辑和显示具有 Rating
字段的电影。 如果数据库未设定种子,则在 SeedData.Initialize
方法中设置断点。
在此部分中,Entity Framework Code First 迁移用于:
使用 EF Code First 自动创建和跟踪数据库时,Code First 将:
__EFMigrationsHistory
表格,以跟踪数据库的架构是否与从生成它的模型类同步。自动验证架构与模型是否同步可以更容易地发现不一致的数据库代码问题。
打开 Models/Movie.cs
文件并添加 Rating
属性:
public class Movie
{
public int ID { get; set; }
public string Title { get; set; } = string.Empty;
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; } = string.Empty;
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
public string Rating { get; set; } = string.Empty;
}
编辑 Pages/Movies/Index.cshtml
,并添加 Rating
字段:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie)
{
<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>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
使用 Rating
字段更新以下页面:
在数据库更新为包括新字段之前,应用将不会正常工作。 在不更新数据库的情况下运行应用会引发 SqlException
:
SqlException: Invalid column name 'Rating'.
SqlException
异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。 数据库表中没有 Rating
列。
可通过几种方法解决此错误:
对于本教程,请使用 Code First 迁移。
更新 SeedData
类,使它提供新列的值。 示例更改如下所示,但对每个 new Movie
块做出此更改。
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M,
Rating = "R"
},
生成解决方案。
从“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。
在 PMC 中,输入以下命令:
Add-Migration Rating
Update-Database
Add-Migration
命令会通知框架执行以下操作:
Movie
模型与 Movie
数据库架构进行比较。名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
Update-Database
命令指示框架将架构更改应用到数据库并保留现有数据。
删除数据库中的所有记录后,初始化表达式会设定数据库种子,并将包括 Rating
字段。 可以使用浏览器中的删除链接,也可从 SQL Server 对象资源管理器 (SSOX) 进行删除。
另一个方案是删除数据库,并使用迁移来重新创建该数据库。 删除 SSOX 中的数据库:
在 SSOX 中选择数据库。
右键单击数据库,并选择“删除”。
检查“关闭现有连接”。
选择“确定”。
在 PMC 中更新数据库:
Update-Database
运行应用,并验证是否可以创建、编辑和显示具有 Rating
字段的电影。 如果数据库未设定种子,则在 SeedData.Initialize
方法中设置断点。
在此部分中,Entity Framework Code First 迁移用于:
使用 EF Code First 自动创建数据库时,Code First 将:
__EFMigrationsHistory
表格,以跟踪数据库的架构是否与从生成它的模型类同步。自动验证架构与模型是否同步可以更容易地发现不一致的数据库代码问题。
打开 Models/Movie.cs
文件并添加 Rating
属性:
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
public string Rating { get; set; }
}
构建应用程序。
编辑 Pages/Movies/Index.cshtml
,并添加 Rating
字段:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie)
{
<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>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
使用 Rating
字段更新以下页面:
在数据库更新为包括新字段之前,应用将不会正常工作。 在不更新数据库的情况下运行应用会引发 SqlException
:
SqlException: Invalid column name 'Rating'.
SqlException
异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。 数据库表中没有 Rating
列。
可通过几种方法解决此错误:
让 Entity Framework 自动丢弃并使用新的模型类架构重新创建数据库。 此方法在开发周期早期很方便,通过该方法可以一起快速改进模型和数据库架构。 此方法的缺点是会导致数据库中的现有数据丢失。 请勿对生产数据库使用此方法! 在架构更改时丢弃数据库,并使用初始化表达式通过测试数据自动设定数据库种子,这通常是开发应用的有效方式。
对现有数据库架构进行显式修改,使它与模型类相匹配。 此方法的优点是可以保留数据。 可以手动或通过创建数据库更改脚本进行此更改。
使用 Code First 迁移更新数据库架构。
对于本教程,请使用 Code First 迁移。
更新 SeedData
类,使它提供新列的值。 示例更改如下所示,但对每个 new Movie
块做出此更改。
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M,
Rating = "R"
},
生成解决方案。
从“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。
在 PMC 中,输入以下命令:
Add-Migration Rating
Update-Database
Add-Migration
命令会通知框架执行以下操作:
Movie
模型与 Movie
数据库架构进行比较。名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
Update-Database
命令指示框架将架构更改应用到数据库并保留现有数据。
删除数据库中的所有记录后,初始化表达式会设定数据库种子,并将包括 Rating
字段。 可以使用浏览器中的删除链接,也可从 SQL Server 对象资源管理器 (SSOX) 进行删除。
另一个方案是删除数据库,并使用迁移来重新创建该数据库。 删除 SSOX 中的数据库:
在 SSOX 中选择数据库。
右键单击数据库,并选择“删除”。
检查“关闭现有连接”。
选择“确定”。
在 PMC 中更新数据库:
Update-Database
运行应用,并验证是否可以创建/编辑/显示具有 Rating
字段的电影。 如果数据库未设定种子,则在 SeedData.Initialize
方法中设置断点。
在此部分中,Entity Framework Code First 迁移用于:
使用 EF Code First 自动创建数据库时,Code First 将:
__EFMigrationsHistory
表格,以跟踪数据库的架构是否与从生成它的模型类同步。自动验证架构与模型是否同步可以更容易地发现不一致的数据库代码问题。
打开 Models/Movie.cs
文件并添加 Rating
属性:
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
public string Rating { get; set; }
}
构建应用程序。
编辑 Pages/Movies/Index.cshtml
,并添加 Rating
字段:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie)
{
<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>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
使用 Rating
字段更新以下页面:
在数据库更新为包括新字段之前,应用将不会正常工作。 在不更新数据库的情况下运行应用会引发 SqlException
:
SqlException: Invalid column name 'Rating'.
SqlException
异常是由于更新的 Movie 模型类与数据库的 Movie 表架构不同导致的。 数据库表中没有 Rating
列。
可通过几种方法解决此错误:
让 Entity Framework 自动丢弃并使用新的模型类架构重新创建数据库。 此方法在开发周期早期很方便,通过该方法可以一起快速改进模型和数据库架构。 此方法的缺点是会导致数据库中的现有数据丢失。 请勿对生产数据库使用此方法! 在架构更改时丢弃数据库,并使用初始化表达式通过测试数据自动设定数据库种子,这通常是开发应用的有效方式。
对现有数据库架构进行显式修改,使它与模型类相匹配。 此方法的优点是可以保留数据。 可以手动或通过创建数据库更改脚本进行此更改。
使用 Code First 迁移更新数据库架构。
对于本教程,请使用 Code First 迁移。
更新 SeedData
类,使它提供新列的值。 示例更改如下所示,但对每个 new Movie
块做出此更改。
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M,
Rating = "R"
},
生成解决方案。
从“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。
在 PMC 中,输入以下命令:
Add-Migration Rating
Update-Database
Add-Migration
命令会通知框架执行以下操作:
Movie
模型与 Movie
数据库架构进行比较。名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
Update-Database
命令指示框架将架构更改应用到数据库并保留现有数据。
如果删除数据库中的所有记录,初始化表达式会设定数据库种子,并将包括 Rating
字段。 可以使用浏览器中的删除链接,也可以从 Sql Server 对象资源管理器 (SSOX) 执行此操作。
另一个方案是删除数据库,并使用迁移来重新创建该数据库。 删除 SSOX 中的数据库:
在 SSOX 中选择数据库。
右键单击数据库,并选择“删除”。
检查“关闭现有连接”。
选择“确定”。
在 PMC 中更新数据库:
Update-Database
运行应用,并验证是否可以创建/编辑/显示具有 Rating
字段的电影。 如果数据库未设定种子,则在 SeedData.Initialize
方法中设置断点。
文档
Razor 页面教程系列第 5 部分。
Razor 页面教程系列第 6 部分。
Razor 页面教程系列的第 4 部分。
培训