第 8 部分:向 ASP.NET Core MVC 应用添加新字段

注意事项

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

警告

不再支持此版本的 ASP.NET Core。 有关详细信息,请参阅 .NET 和 .NET 核心支持策略。 有关当前发布,请参阅本文的 .NET 10 版本

在本部分,Entity Framework Core 迁移 用于:

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

实体框架 (EF) 用于从模型类自动创建数据库时:

  • 一个表将添加到数据库,以跟踪数据库的架构。
  • 已验证数据库与其生成的模型类保持同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

/Views/Movies/Create.cshtml 更新为 Rating 字段。

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。 IntelliSense 适用于标记帮助程序

开发人员在视图的第二个标签元素中键入了 asp-for 的属性值的字母 R。将显示 Intellisense 上下文菜单,其中显示了可用字段,包括自动在列表中突出显示的“评分”。当开发人员单击该字段或按键盘上的 Enter 时,该值将设置为“评分”。

Rating 属性添加到其余 Create.cshtmlDelete.cshtmlDetails.cshtmlEdit.cshtml 视图模板。

更新 SeedData 类,使它提供新列的值。 以下代码片段中显示了一个示例更改,但你希望对每个 new Movie代码片段进行此更改。

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

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

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

  3. 使用“实体框架迁移”更新数据库架构。

在此教程中使用了“实体框架迁移”。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单。

在Package Manager控制台中,输入以下命令:

Add-Migration Rating

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

在Package Manager控制台中,输入以下命令:

Update-Database

Update-Database 命令在尚未应用的迁移中运行 Up 方法。

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

在此部分中,实体框架迁移用于:

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

实体框架 (EF) 用于从模型类自动创建数据库时:

  • 一个表将添加到数据库,以跟踪数据库的架构。
  • 已验证数据库与其生成的模型类保持同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

/Views/Movies/Create.cshtml 更新为 Rating 字段。

可以复制/粘贴以前的“窗体组”,让 IntelliSense 帮助你更新字段。 IntelliSense 适用于标记帮助程序

开发人员在视图的第二个标签元素中键入字母 R 作为 asp-for 的属性值。此时,Intellisense 上下文菜单出现,显示了可用字段,包括自动在列表中突出显示的“Rating”。当开发人员点击该字段或在键盘上按下 Enter 键时,该值将设置为“Rating”。

Rating 属性添加到其余 Create.cshtmlDelete.cshtmlDetails.cshtmlEdit.cshtml 视图模板。

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

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

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

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

  3. 使用“实体框架迁移”更新数据库架构。

在此教程中使用了“实体框架迁移”。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单

在Package Manager控制台中,输入以下命令:

Add-Migration Rating

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

在Package Manager控制台中,输入以下命令:

Update-Database

Update-Database 命令在尚未应用的迁移中运行 Up 方法。

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

在本部分,Entity Framework Core 迁移 用于:

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

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

  • 将表添加到数据库,以跟踪数据库的架构。
  • 验证数据库与生成它的模型类是否同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

/Views/Movies/Create.cshtml 更新为 Rating 字段。

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。 IntelliSense 适用于标记帮助程序

开发人员在视图的第二个标签元素中键入字母 R 作为 asp-for 的属性值。此时,Intellisense 上下文菜单出现,显示了可用字段,包括自动在列表中突出显示的“Rating”。当开发人员点击该字段或在键盘上按下 Enter 键时,该值将设置为“Rating”。

更新剩余模板。

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

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

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

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

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

对于本教程,使用 Code First Migrations。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单

在 PMC 中,输入以下命令:

Add-Migration Rating
Update-Database

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

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

在本部分,Entity Framework Core 迁移 用于:

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

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

  • 将表添加到数据库,以跟踪数据库的架构。
  • 验证数据库与生成它的模型类是否同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

使用 /Views/Movies/Create.cshtml 字段更新 Rating

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。 IntelliSense 适用于Tag Helpers(标记帮助程序)

开发人员已在视图的第二个标签元素中键入字母 R 用作 asp-for 的特性值。出现了 Intellisense 上下文菜单,其中显示了可用字段,包括在列表中自动突出显示的“Rating”。开发人员单击此字段或在键盘上按 Enter 键时,此值将设置为“Rating”。

更新剩余模板。

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

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

在 DB 更新为包括新字段之前,应用将不会正常工作。 如果程序现在运行,会抛出以下异常 SqlException

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

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

对于本教程,使用 Code First Migrations。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单

在 PMC 中,输入以下命令:

Add-Migration Rating
Update-Database

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

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

在本部分,Entity Framework Core 迁移 用于:

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

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

  • 将表添加到数据库,以跟踪数据库的架构。
  • 验证数据库与生成它的模型类是否同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    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; }
    }
}

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

/Views/Movies/Create.cshtml 更新为 Rating 字段。

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。 IntelliSense 适用于标记帮助程序

开发人员在视图的第二个标签元素中键入字母 R 作为 asp-for 的属性值。此时,Intellisense 上下文菜单出现,显示了可用字段,包括自动在列表中突出显示的“Rating”。当开发人员点击该字段或在键盘上按下 Enter 键时,该值将设置为“Rating”。

更新剩余模板。

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

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

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

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

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

对于本教程,使用 Code First Migrations。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单

在 PMC 中,输入以下命令:

Add-Migration Rating
Update-Database

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

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

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

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

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

  • 将表添加到数据库,以跟踪数据库的架构。
  • 验证数据库与生成它的模型类是否同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    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; }
    }
}

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Rating)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model.Movies)
    {
        <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>

/Views/Movies/Create.cshtml 更新为 Rating 字段。

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。 IntelliSense 适用于标记帮助程序

开发人员在视图的第二个标签元素中键入字母 R 作为 asp-for 的属性值。此时,Intellisense 上下文菜单出现,显示了可用字段,包括自动在列表中突出显示的“Rating”。当开发人员点击该字段或在键盘上按下 Enter 键时,该值将设置为“Rating”。

更新剩余模板。

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

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

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

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

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

对于本教程,使用 Code First Migrations。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单

在 PMC 中,输入以下命令:

Add-Migration Rating
Update-Database

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

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

在本节中,Entity Framework Code First 迁移将用于:

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

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

  • 将表添加到数据库,以跟踪数据库的架构。
  • 验证数据库与生成它的模型类是否同步。 如果它们不同步,EF 则会引发异常。 这使查找不一致的数据库/代码问题变得更加轻松。

向电影模型添加分级属性

Rating 属性添加到 Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    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; }
    }
}

生成应用

Ctrl+Shift+B

因为已经添加新字段到 Movie 类,所以需要更新属性绑定列表,将此新属性纳入其中。 在 MoviesController.cs 中,更新 [Bind]Create 操作方法的 Edit 属性,以包括 Rating 属性:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

更新视图模板以在浏览器视图中显示、创建和编辑新的 Rating 属性。

编辑 /Views/Movies/Index.cshtml 文件并添加 Rating 字段:

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Rating)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model.Movies)
    {
        <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>

/Views/Movies/Create.cshtml 更新为 Rating 字段。

可以复制/粘贴之前的“窗体组”,并让 intelliSense 帮助更新字段。 IntelliSense 适用于标记帮助程序

开发人员在视图的第二个标签元素中键入字母 R 作为 asp-for 的属性值。此时,Intellisense 上下文菜单出现,显示了可用字段,包括自动在列表中突出显示的“Rating”。当开发人员点击该字段或在键盘上按下 Enter 键时,该值将设置为“Rating”。

更新剩余模板。

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

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

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

SqlException: Invalid column name 'Rating'.

发生此错误是因为更新的 Movie 模型类与现有数据库的 Movie 表架构不同。 (数据库表中没有 Rating 列。)

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

  1. 让 Entity Framework 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上进行开发时,此方法在开发周期早期很方便;通过它可以一起快速改进模型和数据库架构。 但其缺点是会丢失数据库中的现有数据 - 因此请勿对生产数据库使用此方法! 使用初始化程序自动向数据库填充测试数据通常是开发应用程序的有效方式。 对于早期开发和使用 SQLite 的情况,这是一个不错的方法。

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

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

对于本教程,使用 Code First Migrations。

Tools 菜单中,选择 NuGet Package Manager > Package Manager Console

PMC 菜单

在 PMC 中,输入以下命令:

Add-Migration Rating
Update-Database

Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。

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

如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。

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