ASP.NET Core 3.0 Razor Pages 事始め(8)の続きです。
今回は公式チュートリアルのASP.NET Core で Razor ページに新しいフィールドを追加するに沿って進めていこうと思います。
モデルへプロパティを追加
soれでは、チュートリアルに沿って進めていきます。まず、Movieモデルへ評価を示すプロパティを追加します。
Models/Movie.cs ファイルを開き、Rating プロパティを追加します。
[Display(Name="レイティング")]publicstringRating{get;set;}
Index.cshtmlを開き、Rating フィールドを追加します。
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
...
<tableclass="table"><thead><tr>
...
<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.Rating)
</td><td><aasp-page="./Edit"asp-route-id="@item.ID">編集</a> |
<aasp-page="./Details"asp-route-id="@item.ID">詳細</a> |
<aasp-page="./Delete"asp-route-id="@item.ID">削除</a></td></tr>
}
</tbody></table>
Create.cshtmlにも、Ratingのフィールドを追加します。
<divclass="form-group"><labelasp-for="Movie.Rating"class="control-label"></label><inputasp-for="Movie.Rating"class="form-control"/><spanasp-validation-for="Movie.Rating"class="text-danger"></span></div>
同様にして、Edit.cshtml, Delete.cshtml, Details.cshtml にもRatingフィールドを追加します。
ビルドして、実行してみます。
しかし、Indexページを開こうとすると、以下の例外が発生してしまいます。
An unhandled exception occurred while processing the request.
SqliteException: SQLite Error 1: 'no such column: m.Rating'.
Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(int rc, sqlite3 db)
これは、データベースのMovie テーブにRatingカラムがまだ存在しないためです。
Code First Migrations
Code First Migrations を利用して、これを解決します。
まず、SeedData
クラスを変更し、Ratingプロパティに値を設定するようにします。
context.Movies.AddRange(newMovie{Title="When Harry Met Sally",ReleaseDate=DateTime.Parse("1989-2-12"),Genre="Romantic Comedy",Price=800M,Rating="R",},newMovie{Title="Ghostbusters ",ReleaseDate=DateTime.Parse("1984-3-13"),Genre="Comedy",Price=900M,Rating="G",},newMovie{Title="Ghostbusters 2",ReleaseDate=DateTime.Parse("1986-2-23"),Genre="Comedy",Price=1000M,Rating="G",},newMovie{Title="Rio Bravo",ReleaseDate=DateTime.Parse("1959-4-15"),Genre="Western",Price=500M,Rating="NA",});
次のコマンドを実行します。
dotnetefdatabasedropdotnetefmigrationsaddaddratingdotnetefdatabaseupdate
最初にDBを削除します。これは、SeedDataでのデータ初期化コードを動かすためです。
以下実行結果の抜粋です。
$ dotnet ef database drop
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
Are you sure you want to drop the database 'main' on server 'MvcMovie.db'? (y/N)
y
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
Dropping database 'main'.
Successfully dropped database 'main'.$ dotnet ef migrations add addrating
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
Done. To undo this action, use 'ef migrations remove'$ dotnet ef database update
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20100]
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
PRAGMA journal_mode ='wal';
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
PRAGMA journal_mode ='wal';
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "__EFMigrationsHistory"("MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY,
"ProductVersion" TEXT NOT NULL
);…
Done.
正常に終了しました。
なお、SQLiteの場合、EFはカラムの変更はサポートしていませんでしたが、試した範囲では、
カラムの追加は大丈夫みたいです。dropでDB削除せずに、マイグレーションを行なってみましたが、正常にコマンドが終了しました。
実行してみる
それでは、実行してみます。
うまく動作しました。
新規追加、編集、詳細なども動作するかを確認します。
ところで、この "R"ってなんだろう? 調べたら、Restricted
の頭文字のようです。
R:17歳未満の子供は同伴する保護者または成人の保護者が必要です。
ということらしいです。G, PG, PG-13, R, NC-17 があるらしいです。
サンプルコードで代入されていた NA
は、評価無しということかな。
入力時も小数点以下を表示しないようにする
ここまで書いて気がついたんですが、
[DisplayFormat(DataFormatString="{0:#,0}")]publicdecimalPrice{get;set;}
と指定してるのに、編集ページ(Edit.cshtml)では、
小数部が表示されてます。この小数部を表示しないようにするには、ApplyFormatInEditMode
プロパティを使えば良いみたいです。
[DisplayFormat(DataFormatString="{0:#,0}",ApplyFormatInEditMode=true)]publicdecimalPrice{get;set;}
これで以下のような表示になりました。
今回はこれでおしまい。いよいよ次回がチュートリアルの最後となります。