Movie モデルとテーブルに新しいフィールドを追加する
作成者 : Rick Anderson
Note
このチュートリアルの更新版は、MVC 5 とVisual Studio 2013 ASP.NET 使用するこちらにあります。 より安全で、従う方がはるかに簡単で、より多くの機能を示します。
このセクションでは、Entity Framework Code First Migrationsを使用してモデル クラスにいくつかの変更を移行し、変更がデータベースに適用されるようにします。
既定では、このチュートリアルで前に行ったように Entity Framework Code First を使用してデータベースを自動的に作成すると、Code First によってデータベースにテーブルが追加され、データベースのスキーマが生成元のモデル クラスと同期しているかどうかを追跡できます。 同期されていない場合、Entity Framework はエラーをスローします。 これにより、実行時に (あいまいなエラーによって) 見つからない可能性がある開発時の問題を簡単に追跡できます。
モデル変更のCode First Migrationsの設定
Visual Studio 2012 を使用している場合は、ソリューション エクスプローラーから Movies.mdf ファイルをダブルクリックしてデータベース ツールを開きます。 Web 用Visual Studio Expressデータベース エクスプローラーが表示され、Visual Studio 2012 にはサーバー エクスプローラーが表示されます。 Visual Studio 2010 を使用している場合は、SQL Server オブジェクト エクスプローラーを使用します。
データベース ツール (データベース エクスプローラー、サーバー エクスプローラー、またはSQL Server オブジェクト エクスプローラー) で MovieDBContext
を右クリックし、 [削除] を選択してムービー データベースを削除します。
ソリューション エクスプローラーに戻ります。 Movies.mdf ファイルを右クリックし、[削除] を選択して movies データベースを削除します。
アプリケーションをビルドしてエラーがないことを確認します。
[ツール] メニューの [NuGet パッケージ マネージャー] をクリックし、[パッケージ マネージャー コンソール] をクリックします。
プロンプトの [パッケージ マネージャー コンソール ] ウィンドウで PM>
、「Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext」と入力します。
Enable-Migrations コマンド (上記) は、新しい Migrations フォルダーに Configuration.cs ファイルを作成します。
Visual Studio によって Configuration.cs ファイルが 開きます。 Seed
Configuration.cs ファイルの メソッドを次のコードに置き換えます。
protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
context.Movies.AddOrUpdate( i => i.Title,
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Price = 7.99M
},
new Movie
{
Title = "Ghostbusters ",
ReleaseDate = DateTime.Parse("1984-3-13"),
Genre = "Comedy",
Price = 8.99M
},
new Movie
{
Title = "Ghostbusters 2",
ReleaseDate = DateTime.Parse("1986-2-23"),
Genre = "Comedy",
Price = 9.99M
},
new Movie
{
Title = "Rio Bravo",
ReleaseDate = DateTime.Parse("1959-4-15"),
Genre = "Western",
Price = 3.99M
}
);
}
下Movie
の赤い波線を右クリックし、[解決] を選択し、MvcMovie.Models を使用します。
これにより、次の using ステートメントが追加されます。
using MvcMovie.Models;
Note
Code First Migrationsは、移行のたびに メソッドをSeed
呼び出します (つまり、パッケージ マネージャー コンソールで update-database を呼び出す)、このメソッドは既に挿入されている行を更新するか、まだ存在しない場合は挿入します。
Ctrl キーを押しながら Shift キーを押しながら B キーを押して、プロジェクトをビルドします。(この時点でビルドしないと、次の手順は失敗します)。
次の手順では、最初の移行用の DbMigration
クラスを作成します。 へのこの移行によって新しいデータベースが作成されます。そのため、前の手順で movie.mdf ファイルを削除しました。
[パッケージ マネージャー コンソール] ウィンドウで、"add-migration Initial" コマンドを入力して初期移行を作成します。 "Initial" という名前は任意であり、作成された移行ファイルに名前を付けるために使用されます。
Code First Migrationsは、({DateStamp}_Initial.cs という名前の) Migrations フォルダーに別のクラス ファイルを作成します。このクラスには、データベース スキーマを作成するコードが含まれています。 移行のファイル名の先頭には、並べ替えに役立つタイムスタンプが付きます。 {DateStamp}_Initial.cs ファイルを調べます。これには、Movie DB の Movies テーブルを作成する手順が含まれています。 次の手順でデータベースを更新すると、この {DateStamp}_Initial.cs ファイルが実行され、DB スキーマが作成されます。 次に、 Seed メソッドが実行され、DB にテスト データが設定されます。
パッケージ マネージャー コンソールで、"update-database" コマンドを入力してデータベースを作成し、Seed メソッドを実行します。
テーブルが既に存在し、作成できないことを示すエラーが発生した場合は、データベースを削除した後、および を実行する前にアプリケーションを実行した update-database
可能性があります。 その場合は、 Movies.mdf ファイルをもう一度削除し、コマンドを update-database
再試行します。 それでもエラーが発生する場合は、移行フォルダーとコンテンツを削除し、このページの上部にある指示から始めます (つまり 、Movies.mdf ファイルを削除してから Enable-Migrations に進みます)。
アプリケーションを実行し、 /Movies URL に移動します。 シード データが表示されます。
ムービー モデルへの評価プロパティの追加
まず、既存Movie
のクラスに新しいRating
プロパティを追加します。 Models\Movie.cs ファイルを開き、次のような プロパティをRating
追加します。
public string Rating { get; set; }
これで、完全な Movie
クラスは次のコードのようになります。
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
public string Rating { get; set; }
}
[Build Movie]\(ムービーのビルド\) メニュー コマンドを使用するか、Ctrl + Shift + B キーを押して、アプリケーションをビルド>します。
クラスを更新Model
したので、ブラウザー ビューに新しいRating
プロパティを表示するために、\Views\Movies\Index.cshtml および \Views\Movies\Create.cshtml ビュー テンプレートも更新する必要があります。
\Views\Movies\Index.cshtml ファイルを開き、Price 列の<th>Rating</th>
直後に列見出しを追加します。 次に、テンプレートの <td>
末尾付近に列を追加して値を @item.Rating
レンダリングします。 更新された Index.cshtml ビュー テンプレートは次のようになります。
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Rating)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<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>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
次に、 \Views\Movies\Create.cshtml ファイルを開き、フォームの末尾付近に次のマークアップを追加します。 これにより、テキスト ボックスがレンダリングされ、新しいムービーの作成時に評価を指定できるようになります。
<div class="editor-label">
@Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
これで、新しい Rating
プロパティをサポートするようにアプリケーション コードが更新されました。
次に、アプリケーションを実行し、 /Movies URL に移動します。 ただし、これを行うと、次のいずれかのエラーが表示されます。
アプリケーションの更新 Movie
されたモデル クラスが既存のデータベースのテーブルのスキーマと異なるため、このエラーが Movie
表示されます。 (データベース テーブルに Rating
列はありません)。
このエラーを解決するための手法がいくつかあります。
- Entity Framework に、新しいモデル クラス スキーマに基づいてデータベースを自動的にドロップさせ、再作成させます。 この方法は、テスト データベースでアクティブな開発を行う場合に非常に便利です。これにより、モデルとデータベース スキーマを一緒に迅速に進化させることができます。 ただし、欠点は、データベース内の既存のデータを失うことです。そのため、運用データベースでこのアプローチを使用 したくない ということです。 初期化子を使用して、テスト データを使用してデータベースを自動的にシード処理することは、多くの場合、アプリケーションを開発するための生産的な方法です。 Entity Framework データベース初期化子の詳細については、Tom Dykstra の mvc/Entity Framework チュートリアル ASP.NET 参照してください。
- モデル クラスに一致するように、既存のデータベースのスキーマを明示的に変更します。 この手法の長所は、データが維持されることです。 この変更は手動で行うことも、データベース変更スクリプトを作成して行うこともできます。
- Code First Migrations を使用して、データベース スキーマを更新します。
このチュートリアルでは、Code First Migrations を利用します。
新しい列の値を提供するように Seed メソッドを更新します。 Migrations\Configuration.cs ファイルを開き、Rating フィールドを各 Movie オブジェクトに追加します。
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Rating = "G",
Price = 7.99M
},
ソリューションをビルドし、[ パッケージ マネージャー コンソール ] ウィンドウを開き、次のコマンドを入力します。
add-migration AddRatingMig
コマンドは add-migration
、現在のムービー DB スキーマを使用して現在のムービー モデルを調べ、DB を新しいモデルに移行するために必要なコードを作成するように移行フレームワークに指示します。 AddRatingMig は任意であり、移行ファイルの名前を付けるために使用されます。 移行手順にわかりやすい名前を使用すると便利です。
このコマンドが完了すると、Visual Studio によって新しい DbMigration
派生クラスを定義するクラス ファイルが開き、メソッドで Up
新しい列を作成するコードを確認できます。
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn("dbo.Movies", "Rating", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Movies", "Rating");
}
}
ソリューションをビルドし、[ パッケージ マネージャー コンソール ] ウィンドウに "update-database" コマンドを入力します。
次の図は、[ パッケージ マネージャー コンソール ] ウィンドウの出力を示しています (AddRatingMig より前の日付スタンプは異なります)。
アプリケーションを再実行し、/Movies URL に移動します。 新しい [評価] フィールドが表示されます。
[ 新規作成 ] リンクをクリックして、新しいムービーを追加します。 評価を追加できることに注意してください。
Create をクリックしてください。 評価を含む新しい映画が映画の一覧に表示されるようになりました。
また、フィールドを Rating
[編集]、[詳細]、[SearchIndex] ビュー テンプレートに追加する必要があります。
[パッケージ マネージャー コンソール] ウィンドウに "update-database" コマンドをもう一度入力しても、スキーマがモデルと一致するため、変更は行われません。
このセクションでは、モデル オブジェクトを変更し、データベースを変更と同期する方法について説明しました。 また、シナリオを試すことができるように、新しく作成したデータベースにサンプル データを設定する方法についても学習しました。 次に、モデル クラスに豊富な検証ロジックを追加し、一部のビジネス ルールを適用できるようにする方法を見てみましょう。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示