パート 8、ASP.NET Core MVC アプリへの新しいフィールドの追加

Note

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の ASP.NET Core 8.0 バージョンをご参照ください。

作成者: Rick Anderson

このセクションでは Entity Framework Code First Migrations を次の目的で使用します。

  • モデルに新しいフィールドを追加する。
  • 新しいフィールドをデータベースに移行する。

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 で、CreateEdit の両方のアクション メソッドの [Bind] 属性を更新して、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.cshtmlRating フィールドで更新します。

前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。

The developer has typed the letter R for the attribute value of asp-for in the second label element of the view. An Intellisense contextual menu has appeared showing the available fields, including Rating, which is highlighted in the list automatically. When the developer clicks the field or presses Enter on the keyboard, the value will be set to 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 Migrations を使用して、データベース スキーマを更新します。

このチュートリアルでは、Code First Migrations を使用します。

[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。

PMC menu

PMC で、次のコマンドを入力します。

Add-Migration Rating
Update-Database

Add-Migration コマンドは移行フレームワークに現在の Movie モデルを現在の Movie DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。

"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。

DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating フィールドが追加されします。

アプリを実行し、Rating フィールドでムービーを作成、編集、表示できることを確認します。

このセクションでは Entity Framework Code First Migrations を次の目的で使用します。

  • モデルに新しいフィールドを追加する。
  • 新しいフィールドをデータベースに移行する。

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 で、CreateEdit の両方のアクション メソッドの [Bind] 属性を更新して、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.cshtmlRating フィールドで更新します。

前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。

The developer has typed the letter R for the attribute value of asp-for in the second label element of the view. An Intellisense contextual menu has appeared showing the available fields, including Rating, which is highlighted in the list automatically. When the developer clicks the field or presses Enter on the keyboard, the value will be set to 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 Migrations を使用して、データベース スキーマを更新します。

このチュートリアルでは、Code First Migrations を使用します。

[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。

PMC menu

PMC で、次のコマンドを入力します。

Add-Migration Rating
Update-Database

Add-Migration コマンドは移行フレームワークに現在の Movie モデルを現在の Movie DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。

"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。

DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating フィールドが追加されします。

アプリを実行し、Rating フィールドでムービーを作成、編集、表示できることを確認します。

このセクションでは Entity Framework Code First Migrations を次の目的で使用します。

  • モデルに新しいフィールドを追加する。
  • 新しいフィールドをデータベースに移行する。

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 で、CreateEdit の両方のアクション メソッドの [Bind] 属性を更新して、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.cshtmlRating フィールドで更新します。

前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。

The developer has typed the letter R for the attribute value of asp-for in the second label element of the view. An Intellisense contextual menu has appeared showing the available fields, including Rating, which is highlighted in the list automatically. When the developer clicks the field or presses Enter on the keyboard, the value will be set to 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 Migrations を使用して、データベース スキーマを更新します。

このチュートリアルでは、Code First Migrations を使用します。

[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。

PMC menu

PMC で、次のコマンドを入力します。

Add-Migration Rating
Update-Database

Add-Migration コマンドは移行フレームワークに現在の Movie モデルを現在の Movie DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。

"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。

DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating フィールドが追加されします。

アプリを実行し、Rating フィールドでムービーを作成、編集、表示できることを確認します。

このセクションでは Entity Framework Code First Migrations を次の目的で使用します。

  • モデルに新しいフィールドを追加する。
  • 新しいフィールドをデータベースに移行する。

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 で、CreateEdit の両方のアクション メソッドの [Bind] 属性を更新して、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.cshtmlRating フィールドで更新します。

前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。

The developer has typed the letter R for the attribute value of asp-for in the second label element of the view. An Intellisense contextual menu has appeared showing the available fields, including Rating, which is highlighted in the list automatically. When the developer clicks the field or presses Enter on the keyboard, the value will be set to 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 Migrations を使用して、データベース スキーマを更新します。

このチュートリアルでは、Code First Migrations を使用します。

[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。

PMC menu

PMC で、次のコマンドを入力します。

Add-Migration Rating
Update-Database

Add-Migration コマンドは移行フレームワークに現在の Movie モデルを現在の Movie DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。

"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。

DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating フィールドが追加されします。

アプリを実行し、Rating フィールドでムービーを作成、編集、表示できることを確認します。

このセクションでは Entity Framework Code First Migrations を次の目的で使用します。

  • モデルに新しいフィールドを追加する。
  • 新しいフィールドをデータベースに移行する。

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 で、CreateEdit の両方のアクション メソッドの [Bind] 属性を更新して、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.cshtmlRating フィールドで更新します。

前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。

The developer has typed the letter R for the attribute value of asp-for in the second label element of the view. An Intellisense contextual menu has appeared showing the available fields, including Rating, which is highlighted in the list automatically. When the developer clicks the field or presses Enter on the keyboard, the value will be set to 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 Migrations を使用して、データベース スキーマを更新します。

このチュートリアルでは、Code First Migrations を使用します。

[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。

PMC menu

PMC で、次のコマンドを入力します。

Add-Migration Rating
Update-Database

Add-Migration コマンドは移行フレームワークに現在の Movie モデルを現在の Movie DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。

"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。

DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating フィールドが追加されします。

アプリを実行し、Rating フィールドでムービーを作成、編集、表示できることを確認します。