はじめてのRazorらぞぅ(2)

昨日の続きです。

目標
CRUDのスケルトンを動かしてテストの書き方を把握するところまで。

やったこと

次のチュートリアルで、Viewの整形から、Modelを追加してDBアクセスするあたりまでやりました。

学んだこと

Controllerから投げたViewBagオブジェクトにViewからアクセスして、レスポンスを整形する。

ViewBagは「動的で、強く型付けされていない」オブジェクト。だからインテリセンスが効かないのか。

Viewの整形

チュートリアルどおりに次のようなViewを書くと、ViewBag.numTimesが0の場合、余分なulタグが出力されてしまう。

<h2>Welcome</h2>
<ul>
    @for (int i = 0; i < ViewBag.numTimes; i++)
    {
        <li>@ViewBag.Message</li>
    }
</ul>

出力。

<h2>Welcome</h2>
<ul>
</ul>

次のように書けば、0件のときには出力されなくなる。冗長な感じだけどしかたないのかな。

<h2>Welcome</h2>
@if(0 < ViewBag.numTimes){
<ul>
    @for (int i = 0; i < ViewBag.numTimes; i++)
    {
        <li>@ViewBag.Message</li>
    }
</ul>
}
POCO(Plain-old CLR objects)からDBを生成する

Entity Frameworkを使って、コードファーストというパラダイムに則り、クラスからDBを生成する。ちょっと自分の好みと違いますが、がたがたいわずに一度作ってみることにします。

  • Viewを作成するとき: Controllerのソースコード内のアクションメソッドの中にカーソルを合わせて、右クリック→Add View
  • Modelを作成するとき: Modelフォルダを選択して、右クリック→Add→Classを選択

この違い。ViewはControllerありきだけど、Modelはそうではないってことでしょうか。関係ない?

データベースの設定

Web.configに書く。接続文字列の意味は、次のページを参照する。

Controllerの追加

作成済みのModelとDBコンテキストを指定し、CRUD処理のためのViewを同時に作成する。

Controllerを追加するダイアログでは、Modelクラスを1つだけ指定できる。1つのControllerから複数のModelを触るにはどうすればよいのか分からない。あとで確認する。

ダイアログを最後まで進めると、Viewsフォルダ以下に、このController専用のフォルダが生成される。

  • 自動生成されたViewページ群
    • Create.cshtml
    • Detail.cshtml
    • Details.cshtml
    • Edit.cshtml
    • Index.cshtml(デフォルト?)

各ページはCRUD(と一覧)操作に対応している。

これらの自動生成は、Scafoolding optionsでTemplateを指定したため、あるいは、ViewsにRazorを指定した結果として行われた、のだと思う。実際、Empty MVC Controllerを選択すれば、Views以下には何も作成されず、Viewを手動で追加することになる。

  • Controllerクラスに自動生成されたアクションメソッド群
    • Index(デフォルト?)
    • Details
    • Create #GET
    • Create #POST
    • Edit #GET
    • Edit #POST
    • Delete #GET
    • Delete #POST
    • Dispose

GET用のメソッドが、CRUD操作用のページ表示に使われ、POSTが処理実行に使われるのだと思う。まだよく見てないけど。

Disposeメソッド is 何。あとで調べる。

デバッグ実行するとCRUDが動いた
  • 日付表記の変更方法
  • Create処理に誘導するリンクラベル「Create New」などのリソースファイル化(多言語対応)

このへんがわからない。あとで調べる。

LocalDB

Web.configでデータベース接続文字列を書いたが、データベースの実体(?)を確認する。

  1. VisualStudioのSQL Server Object Explorerを開く
  2. (localdb)\v11.0\Databases\{AttachDbFilenameで指定した名前}\Tables\dbo.{DBContextで指定した名前} を右クリック→[View Data]

ハマったところ

ModelからDBを作成した後、Modelを作る直前のコミットに戻した(git resetした)ところ、実行時にInvalidOperationExceptionが出ました。

The model backing the '{DBContext名}' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

はい……。

解決法

Global.asaxcsのApplication_Startメソッドに次を記述する。

Database.SetInitializer<Models.MovieDBContext>(null);

using System.Data.Entityも忘れずに。

アプリケーション全体のライフサイクルをまだよく分かっていないので、対処療法的ですね。ごめんなさい。