パート 8、ASP.NET Core MVC アプリへの新しいフィールドの追加
Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
作成者: Rick Anderson
このセクションでは Entity Framework Migrations を次の目的で使用します。
- モデルに新しいフィールドを追加する。
- 新しいフィールドをデータベースに移行する。
Entity Framework (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
で、Create
と Edit
の両方のアクション メソッドの [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.cshtml
を Rating
フィールドで更新します。
前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。
Rating
プロパティを、残りの Create.cshtml
、Delete.cshtml
、Details.cshtml
、Edit.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
列はありません)。
このエラーを解決するための手法がいくつかあります。
Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この手法は、開発周期の早い段階で、テスト データベースで開発しているときに非常に便利です。モデルとデータベース スキーマを一緒に短期間で発展させることができます。 ただし、欠点もあり、データベースの既存データが失われます。本稼働データベースではこの手法は推奨されません。 初期化子を利用し、データベースにテスト データを自動的に初期投入します。多くの場合、アプリケーション開発の手法として有益な方法です。 これは、初期の開発や SQLite を使用するときに適した方法です。
モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
Entity Framework Migrations を使用してデータベース スキーマを更新します。
このチュートリアルでは、Entity Framework Migrations を使用します。
[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。
パッケージ マネージャー コンソールで、次のコマンドを入力します。
Add-Migration Rating
Add-Migration
コマンドは移行フレームワークに現在の Movie
モデルを現在の Movie
DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。
"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。
DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating
フィールドが追加されします。
パッケージ マネージャー コンソールで、次のコマンドを入力します。
Update-Database
Update-Database コマンドにより、適用されていない移行で Up メソッドが実行されます。
アプリを実行し、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
で、Create
と Edit
の両方のアクション メソッドの [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.cshtml
を Rating
フィールドで更新します。
前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。
残りのテンプレートを更新します。
新しい列に値を提供するように、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
列はありません)。
このエラーを解決するための手法がいくつかあります。
Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この手法は、開発周期の早い段階で、テスト データベースで開発しているときに非常に便利です。モデルとデータベース スキーマを一緒に短期間で発展させることができます。 ただし、欠点もあり、データベースの既存データが失われます。本稼働データベースではこの手法は推奨されません。 初期化子を利用し、データベースにテスト データを自動的に初期投入します。多くの場合、アプリケーション開発の手法として有益な方法です。 これは、初期の開発や SQLite を使用するときに適した方法です。
モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
Code First Migrations を使用して、データベース スキーマを更新します。
このチュートリアルでは、Code First Migrations を使用します。
[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。
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
で、Create
と Edit
の両方のアクション メソッドの [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.cshtml
を Rating
フィールドで更新します。
前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。
残りのテンプレートを更新します。
新しい列に値を提供するように、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
列はありません)。
このエラーを解決するための手法がいくつかあります。
Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この手法は、開発周期の早い段階で、テスト データベースで開発しているときに非常に便利です。モデルとデータベース スキーマを一緒に短期間で発展させることができます。 ただし、欠点もあり、データベースの既存データが失われます。本稼働データベースではこの手法は推奨されません。 初期化子を利用し、データベースにテスト データを自動的に初期投入します。多くの場合、アプリケーション開発の手法として有益な方法です。 これは、初期の開発や SQLite を使用するときに適した方法です。
モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
Code First Migrations を使用して、データベース スキーマを更新します。
このチュートリアルでは、Code First Migrations を使用します。
[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。
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
で、Create
と Edit
の両方のアクション メソッドの [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.cshtml
を Rating
フィールドで更新します。
前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。
残りのテンプレートを更新します。
新しい列に値を提供するように、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
列はありません)。
このエラーを解決するための手法がいくつかあります。
Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この手法は、開発周期の早い段階で、テスト データベースで開発しているときに非常に便利です。モデルとデータベース スキーマを一緒に短期間で発展させることができます。 ただし、欠点もあり、データベースの既存データが失われます。本稼働データベースではこの手法は推奨されません。 初期化子を利用し、データベースにテスト データを自動的に初期投入します。多くの場合、アプリケーション開発の手法として有益な方法です。 これは、初期の開発や SQLite を使用するときに適した方法です。
モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
Code First Migrations を使用して、データベース スキーマを更新します。
このチュートリアルでは、Code First Migrations を使用します。
[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。
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
で、Create
と Edit
の両方のアクション メソッドの [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.cshtml
を Rating
フィールドで更新します。
前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。
残りのテンプレートを更新します。
新しい列に値を提供するように、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
列はありません)。
このエラーを解決するための手法がいくつかあります。
Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この手法は、開発周期の早い段階で、テスト データベースで開発しているときに非常に便利です。モデルとデータベース スキーマを一緒に短期間で発展させることができます。 ただし、欠点もあり、データベースの既存データが失われます。本稼働データベースではこの手法は推奨されません。 初期化子を利用し、データベースにテスト データを自動的に初期投入します。多くの場合、アプリケーション開発の手法として有益な方法です。 これは、初期の開発や SQLite を使用するときに適した方法です。
モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
Code First Migrations を使用して、データベース スキーマを更新します。
このチュートリアルでは、Code First Migrations を使用します。
[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。
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
で、Create
と Edit
の両方のアクション メソッドの [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.cshtml
を Rating
フィールドで更新します。
前の "form group" をコピー/貼り付けし、intelliSense にフィールドを更新させることができます。 IntelliSense はタグ ヘルパーと連動します。
残りのテンプレートを更新します。
新しい列に値を提供するように、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
列はありません)。
このエラーを解決するための手法がいくつかあります。
Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この手法は、開発周期の早い段階で、テスト データベースで開発しているときに非常に便利です。モデルとデータベース スキーマを一緒に短期間で発展させることができます。 ただし、欠点もあり、データベースの既存データが失われます。本稼働データベースではこの手法は推奨されません。 初期化子を利用し、データベースにテスト データを自動的に初期投入します。多くの場合、アプリケーション開発の手法として有益な方法です。 これは、初期の開発や SQLite を使用するときに適した方法です。
モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
Code First Migrations を使用して、データベース スキーマを更新します。
このチュートリアルでは、Code First Migrations を使用します。
[ツール] メニューで、[NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に選択します。
PMC で、次のコマンドを入力します。
Add-Migration Rating
Update-Database
Add-Migration
コマンドは移行フレームワークに現在の Movie
モデルを現在の Movie
DB スキーマで調べ、DB を新しいモデルに移行するために必要なコードを作成します。
"Rating (評価)" という名前は任意です。移行ファイルに名前を付けるために利用されます。 移行ファイルには意味のある名前を使用すると便利です。
DB 内のレコードをすべて削除すると、初期化メソッドで DB がシードされ、Rating
フィールドが追加されします。
アプリを実行し、Rating
フィールドでムービーを作成、編集、表示できることを確認します。
ASP.NET Core