添加新字段

将新字段添加到 ASP.NET Core 中的 Razor 页面

作者:Rick Anderson

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

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

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

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

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

向电影模型添加分级属性

打开 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>
        Title: <input type="text" asp-for="SearchString" />
        <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 字段添加到“删除”和“详细信息”页面。
  • 使用 Rating 字段更新 Create.cshtml
  • Rating 字段添加到“编辑”页面。

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

SqlException: Invalid column name 'Rating'.

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

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

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

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

  3. 使用 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"
    },

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

生成解决方案。

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

其他资源