はじめてのRazorらぞぅ(2)
昨日の続きです。
- はじめてのRazorらぞぅ http://d.hatena.ne.jp/torazuka/20130723/dotnetmvc
やったこと
次のチュートリアルで、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 何。あとで調べる。
LocalDB
Web.configでデータベース接続文字列を書いたが、データベースの実体(?)を確認する。
- VisualStudioのSQL Server Object Explorerを開く
- (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も忘れずに。
アプリケーション全体のライフサイクルをまだよく分かっていないので、対処療法的ですね。ごめんなさい。
- (参考)The model backing the
context has changed since the database was created http://stackoverflow.com/questions/3600175/the-model-backing-the-database-context-has-changed-since-the-database-was-crea