連載:〜ScottGu氏のブログより〜Entity Framework 4でコード・ファースト開発Scott Guthrie 著/Chica 訳2010/07/20 |
|
|
.NET Framework 4では、System.Data.Entity名前空間にあるデータ・アクセス・ライブラリであるEntity Framework(EF)の大幅に改善されたバージョンが一緒に出荷されます。
Entity Frameworkが.NET Framework 3.5 SP1で最初に導入されたとき、開発者はその最初のリリースで不完全であると思われる点ついて、多くのフィードバックをくれました。SQLチームはこのフィードバックを聞き入れ、.NET 4と一緒に出荷されるEFでそれに対処できるように本当に努力しました。
EF 4の大きな改善点には以下のものがあります。
- POCOサポート:ベース・クラスまたはデータ保存属性なしでエンティティを定義できます。
- レイジー・ローディングのサポート:最初からロードせずに、要求に応じてモデルのサブオブジェクトをロードできます。
- N層サポートと自己追跡エンティティ:層やステートレスなWeb呼び出しにまたがってエンティティが渡るようなシナリオへの対応。
- 改善されたSQL文生成とSPROCサポート:EF 4はより改善されたSQL文を実行でき、SPROC(ストアドプロシージャ)とも、よりうまく統合できます。
- 自動複数形のサポート:EF 4には自動的なテーブルの複数形サポートが含まれます(例:Categories->Category)。
- テスト性の改善:EF 4のオブジェクト・コンテキストはインターフェイスを使用してより簡単に偽造できます。
- 改善されたLINQ演算子サポート:EF 4はLINQ演算子を完全にサポートしています。
Visual Studio 2010には現在、よりリッチになったEFのデザイナとツール・サポートが含まれています。VS 2010のEFデザイナは既存のデータベースからデザイン上にモデル層を構築する“データベース・ファースト”開発スタイルをサポートしています。またデザイン画面を使用してモデル層をまず定義し、それを使って、そこからデータベースのスキーマを生成する“モデル・ファースト”開発スタイルもサポートしています。
EFでコード・ファースト開発
デザイン・ベースの開発ワークフローのサポート以外に、EF 4は、よりコード中心のオプションも可能にしており、それを“コード・ファースト開発”と呼んでいます。コード・ファースト開発は非常に快適な開発ワークフローを可能にします。これにより以下のことが可能になります。
- デザイナを開いたり、XMLマッピング・ファイルを定義したりする必要なく開発できる
- ベース・クラスなしの“プレーン・オールド・クラス(plain old classes)”を書くだけで、モデル・オブジェクトを定義できる
- 特に明示的に設定を行わなくてもデータベースの永続化が可能な“設定に勝る規約(convention over configuration)”方式を使用できる
- オプションとして、規約ベースの永続化をオーバーライドし、永続化のマッピングを完全にカスタマイズするための便利なコードAPIが使用できる
EFの“コード・ファースト開発”サポートは現時点では別途ダウンロードし、.NET 4にビルトインされているコアのEF上で実行することで使用できるようになります。この“コード・ファースト”ライブラリのCTP 4が、今週出荷され、ここでダウンロードできます。
これはVS 2010で動作し、どの.NET 4プロジェクトでも使用できます(ASP.NET Webフォームおよび ASP.NET MVCの両方を含む)。
ステップバイステップ・チュートリアル:コード・ファースト方法を使用してNerdDinnerを構築
去年、ASP.NET MVC 1.0のチュートリアルを書いてオンラインと書籍の両方で公開しました。そのチュートリアルは、“NerdDinner”という簡単なアプリケーションを作成するウォークスルーで、簡単にオンラインで夕食会を企画、ホスト、RSVPする方法を提供します。ここで元のASP.NET V1 NerdDinnerチュートリアルが読めます。チュートリアルの更新版も新しいProfessional ASP.NET MVC 2という書籍の中にあります。
NerdDinnerチュートリアルは“データベース・ファースト方式”を使用しており、データベース・スキーマを最初に定義してから、Visual Studioデザイナを使用して、それにマップするLINQ to SQL/LINQ to Entitiesのモデル・オブジェクトを作成します。
以下では、NerdDinnerモデル層とデータベース・スキーマを構築するためにEF 4を使用する“コード・ファースト方式”を代わりに使用し、ASP.NET MVCを使ってCRUDアプリケーションを構築する方法を紹介していきます。
図1 |
このアプリケーションの構築をステップごとにウォークスルーしていきます。サンプルの完全版へのダウンロード・リンクはこのブログ投稿の最後にあります。
ステップ1:新しい空のASP.NET MVC 2アプリケーションを作成
新しいASP.NET MVC 2プロジェクトをVisual Studio 2010内でまず作成します。これを行うには、メニューバーから[ファイル]−[新規作成]−[プロジェクト]を選択し“ASP.NET MVC 2 空の Web アプリケーション”プロジェクト・テンプレートを使用します。
これにより、コントローラ、モデル、ビューのいずれも含まれていない、空のASP.NET MVC 2プロジェクトが作成されます。
図2 |
次はNerdDinner“モデル”を定義します。これはアプリケーションのデータや、関連する検証やビジネス・ルールを統合した対応ドメインのロジックを表すオブジェクトを参照します。そのモデルはMVCベースのアプリケーションの“心臓部分”であり、基本的にその動作を制御します。新しいEF 4の“コード・ファースト”機能を使用して、このモデル層を作成します。
ステップ2:モデルの作成
データベースはまだ定義されていなく、まったくの最初から、新しくNerdDinnerアプリケーションを構築すると仮定しましょう。
■データベースから開始する必要はありません
コード・ファースト開発のワークフローを使用するとき、データベースの作成やスキーマの指定からアプリケーションを開始する必要はありません。その代わりに、アプリケーションに最も適切なドメイン・モデル・オブジェクトを定義する標準の.NETクラスを書くことから始めます(それらとデータ永続化ロジックの混在を心配する必要はありません)。
■モデル・クラスの作成
NerdDinnerは小さなアプリケーションなので、そのデータ保存のニーズは非常に単純です。参加可能な特定のイベントを参照する“Dinners”を定義して保存したいと思っています。また、ある特定の夕食会の参加に興味があるかどうかの追跡に使用される“RSVP”承諾の定義と保存も行いたいと思っています。
では2つのクラス(DinnerとRSVP)を作成して、これらの概念を表してみましょう。これを行うために2つの新しいクラス、“Dinner”および“RSVP”をASP.NET MVCプロジェクトに追加します。
図3 |
上記の“Dinner”と“RSVP”モデル・クラスは“プレーン・オールドCLRオブジェクト”(別名POCO)です。それらはベース・クラスから継承したり、インターフェイスを実装したりする必要はありません。公開されているプロパティは標準の.NETデータ型です。それらにはデータ保存の属性やデータ・コードは追加されていません。
特定のデータベース、データベースAPI、データベース・スキーマの実装と結び付ける必要なくモデル・クラスを定義できる機能は非常に強力で、データ・アクセスへのより高い柔軟性が得られます。それにより永続化についての実装を気にする必要なく、アプリケーション/ビジネスのニーズに集中できるようになります。またそれらとやり取りするモデル・オブジェクトやコードを書き換える必要なく、将来的にデータベースのスキーマまたはストレージの実装を変更できる柔軟性も得られます。
■データベースの永続化を処理するコンテキスト・クラスの作成
2つのPOCOモデル・クラスが定義できたので、DinnerとRSVPのインスタンスをデータベースから取得/保存する処理に使用するクラスを作成しましょう。
このクラスに“NerdDinners”という名前を付けます。これはDbContextベース・クラスを継承し、2つのpublicプロパティを公開します。1つがDinnerオブジェクトを公開し、1つがRSVPオブジェクトを公開します。
図4 |
上記で使用されているDbContextおよびDbSetクラスはEF 4コード・ファースト・ライブラリの一部として提供されます。これらのクラスを参照するためにSystem.Data.Entity.CTPアセンブリへの参照を追加する必要があります。これは、\Program Files\Microsoft ADO.NET Entity Framework Feature CTP4\Binariesディレクトリへインストールされます。また“NerdDinners”クラス・ファイルの先頭に“using System.Data.Entity”名前空間ステートメントも追加します。
■これが書く必要のあるすべてのコードです
上記3つのクラスにはNerdDinnerアプリケーション用の基礎モデルとデータ永続化層を実装するために必要なすべてのコードが含まれています。データベースからデータを取得したり、それを更新したり、保存するためのクラスを使用するために、新たにデータベースのスキーマのマッピング情報を構成したり、XMLファイルを編集したり、デザイナを使用したりする必要はありません。
規約ベースの永続化マッピング
データベースへモデル・クラスをマップするために、新たにコードを書いたり、XMLファイルを作成したり、ツールを使用したりする必要はありません。どうすればそんなことが可能なのか? と思われるかもしれません。
デフォルトでは、EFのコード・ファーストは“設定に勝る規約”方式をサポートしており、明示的に設定する代わりに、共通のマッピング規約に頼ります。もし独自のデータベース・マッピング・ルールを適用したいなら、これらの規約をオーバーライドできます。もし単純にデフォルトの規約を使用するだけであれば、書く必要のあるコードの量は非常に小さくなります。90%のよくあるシナリオでは、ほかにコードや設定がなくても、期待とおりの方法で“実際に動作します”。
上記の例では、NerdDinnerのコンテキスト・クラスは、デフォルトでその“Dinner”と“RSVP”プロパティを、データベースの“Dinner”と“RSVP”のテーブルにマップします。Dinnersテーブル内の各行は“Dinner”クラスのインスタンスへマップされます。同じく、RSVPテーブル内の各行は“RSVP”クラスのインスタンスにマップされます。そして“Dinner”と“RSVP”クラス内のプロパティがそれぞれ、“Dinner”と“RSVP”データベースのテーブル内のカラムへマップされます。
EFでサポートされているそのほかのデフォルトの規約には、共通の名前付けパターンに基づいて、自動的にプライマリ・キーと外部キーを確認する機能が含まれています(例:DinnerクラスのIDであるDinnerIDプロパティは、プライマリ・キーとして推測されます)。EFはまた、モデル間の関連のあるリレーションシップを接続するスマートな規約も含まれています。デフォルト・セットの規約がどのように動作するかについての詳細を話しているEFチームによるブログ投稿がここにあります。
モデルの使用方法のコード例
先に作成した3つのクラスには、NerdDinnerでモデルおよびデータの永続化を実装するために必要なすべてのコードが含まれています。データについての共通的なシナリオを実行するために、これらのクラスをどのように使用するのか、いくつかのコード例を見てみましょう。
■LINQ式を使用したクエリ
以下のようなコードを使用して、LINQのクエリ式を書いてデータベースからデータを取得できます。以下はLINQ式を使用して、今後発生するすべての夕食会を取得しています。
図5 |
LINQ式を書くときには、DinnerとRSVP間のリレーションシップを活用することもできます。以下では、RSVPの数が0以上の夕食会を“where”ステートメントでフィルタしています。
図6 |
上記クエリ(少なくとも1つのRSVPがある夕食会のみを取得)の“where”フィルタはデータベース・サーバ上で実行されます。これはクエリおよび取得するデータ量を非常に効率的にします。
■1つのインスタンスを取得
ラムダ式でLINQのSingleメソッドを使用して、以下のようなコードでDinnerのインスタンスを1つ取得できます。
図7 |
また、EFの“コード・ファースト”が公開しているFindメソッドを活用することもでき、それにより簡単にIDに基づいたインスタンスを取得できます。
図8 |
■新しいDinnerの追加
以下のコードは、データベースへ新しいDinnerを作成して追加する方法を示しています。必要なのは、Dinnerオブジェクトを“new”し、プロパティを設定して、NerdDinnerコンテキスト・オブジェクトのDinnerプロパティにそれを追加することだけです。NerdDinnerコンテキスト・クラスはコンテキストへ複数のモデルを追加できるように“作業単位(unit of work)”パターンをサポートしており、そのため、1つのアトミックなトランザクションと同様に、データベースへすべての変更を保存するために、“SaveChanges()”を呼び出すことができます。
図9 |
■Dinnerの更新
以下のコードでは、Dinner取得、そのプロパティの更新、そしてデータベースへそれらの変更を保存する方法を表しています。
図10 |
ステップ3:モデルを使用するASP.NET MVCコントローラの作成
モデルに関連する、より完全なシナリオについて見てみましょう。そこではコントローラ・クラスを使用して、今後発生する夕食会の一覧を発行するため、あるいはユーザーが新規の夕食会を追加できるようにするために必要な機能を実装します。
図11 |
“Controllers”フォルダを右クリックして[Add]−[Controller]メニュー・コマンドを選択し、この機能を実装します。新しいコントローラを“HomeController”と名付けます。
そして、EF“コード・ファースト”を使用して先に作成したNerdDinnerモデルとともに動作する、3つの“アクション・メソッド”をその中に追加します。
図12 |
上記の“Index”アクション・メソッドは、今後発生する夕食会を取得して表示します。
“Create”アクション・メソッドではユーザーが新しい夕食会を作成できます。上記の最初の“Create”メソッドは、ユーザーが/Home/CreateというURLを訪れたときに“HTTP GET”シナリオを処理し、“新規夕食会”の入力用のフォームを送り返します。2つ目の“Create”メソッドは、そのフォームに関連する“HTTP POST”シナリオを処理し、データベースへその夕食会を保存します。もし検証エラーがあれば、適切なエラー・メッセージを付けてそのフォームをユーザーに再表示します。
■コントローラへビューを追加
次のステップは、2つの“ビュー・テンプレート”をプロジェクトへ追加します。1つが“Index”用で、もう1つが“Create”用です。
コントローラのIndexアクション・メソッド内へカーソルを移動し、右クリックして[Add View]メニュー・コマンドを選択し、“Index”ビューをプロジェクトへ追加します。これにより“Add View”ダイアログが立ち上がります。強く型付けされたビューを作成することと、それに対して“Dinner”モデル・オブジェクトのIEnumerableリストで引き渡すことを指定します。
図13 |
“Add”をクリックすると、Visual Studioは/Views/Home/Index.aspxを作成します。それでは、Dinnerの<ul>リストを生成する以下のコードを追加して、Createアクションへリンクするハイパーリンクを描画しましょう。
図14 |
コントローラのCreateアクション・メソッド内へカーソルを動かし、右クリックで[Add View]メニュー・コマンドを選択して“Create”ビューをプロジェクトへ追加します。“Add View”ダイアログ内で、強く型付けされたビューを作成することとDinnerオブジェクトを引き渡すことを指定します。また“Create”テンプレートを使用して“スキャフォールド”することも示します。
図15 |
“Add”をクリックすると、Visual Studioは“Dinner”オブジェクトに対してHTMLの<form>を出力する、いくつかのスキャフォールド生成されたコンテンツが含まれた/Views/Home/Create.aspxファイルを作成します。それを少し調整して、DinnerIDプロパティに対する入力要素を削除します。最終的なビュー・テンプレートのコンテンツは次のようになります。
図16 |
これでWebアプリケーションのDinnerの一覧化および作成機能を実装するために、コントローラやビュー内に書く必要のあるすべてのコードが実装できました。
ステップ4:データベース
コードが書けたので、アプリケーションを実行してみましょう。
■でもデータベースはどうするの?
まだデータベースがありませんが、いままでのところ必要としていません。それは“コード・ファースト”開発のワークフローでは、モデル・クラスを定義して使用するために、データベースが必要ないからです。
しかし実際にアプリケーションを実行したときにはDinnerやRSVPオブジェクトを保存したいので、データベースが必要になります。データベースの作成には2通りの方法があります。
- データベース・ツール(すなわち、SQL Management StudioやVisual Studio) を使用して、手動でスキーマを作成、定義する
- EFコード・ファースト・ライブラリを使用して、モデル・クラスから直接スキーマを自動で作成、定義する
この2つ目のオプションは非常にクールなので、これをNerdDinnerアプリケーションでは使用していきます。
■データベース接続文字列の構成
まず接続文字列を設定して、ライブにしたいデータベースを指定します。これを行うために、以下のように“NerdDinners”接続文字列のエントリをアプリケーションのweb.configファイルに追加します。
図17 |
デフォルトでは、DbContextクラスをEFコード・ファーストで作成すると、コンテキスト・クラスの名前に一致した接続文字列が検索されます。コンテキスト・クラスの名前を“NerdDinners”にしたので、ASP.NETアプリケーション内でインスタンス化されたとき、デフォルトでは上記の“NerdDinners”データベース接続文字列が探されて使用されます。
■SQL CE 4の活用
EFコード・ファーストでSQL Server、SQL Server Express、MySQLなどを含む多くの異なるデータベースが使用できます。
2週間前、組み込みSQL Server CE 4データベース・エンジンをASP.NET内で動作できるようにするための開発を行っていることについてブログ投稿しました。SQL CE 4は無償で簡単にセットアップできる軽量のファイル・ベースのデータベースで、ASP.NETアプリケーションに組み込めます。低費用のホスト環境をサポートし、簡単にデータベースをSQL Serverとマイグレートできます。
モデル層を定義(再定義)している初期段階にあり、データベースを簡単に作成、再作成したい場合には、SQL CEは便利なオプションになります。まずSQL CE 4を使用してNerdDinnerアプリケーションを開発します。アプリケーション内で1行のコードも変更することなく、オプションとして、本番のデプロイでSQL Server ExpressまたはSQL Serverを使用する接続文字列に後で変更できます。
上記で指定した接続文字列は、NerdDinners.sdfデータベース・ファイルをポイントしていて、SQL CE 4データベース・プロバイダを指定しています。これを動作させるためにはスタンドアロンSQL CEインストーラを通じて、またはWebMatrix(SQL CE 4がビルトインされています)をインストールするなどして、SQL CE 4をインストールする必要があります。SQL CE 4のダウンロードは、インストールするのに数秒しかかからない小さなものです。
重要:上記の接続文字列には|DataDirectory|フォルダ内にNerdDinners.sdfを作成したいということを示しています。ASP.NETアプリケーションではアプリケーション・ディレクトリの直下にある\App_Data\フォルダになります。デフォルトでは“空のASP.NET MVC Webアプリケーション”プロジェクト・テンプレートはこのディレクトリを作成しません。プロジェクト内でこのディレクトリを明示的に作成する必要があります(プロジェクトを右クリックして[Add]−[ASP.NET Folder]−[Add_Data]メニュー項目を選択)。
■データベース・スキーマの自動作成
EFコード・ファーストはこれらのステップを手動で実行しなくてもいいように、自動的にデータベース・スキーマを生成し、モデル・クラスからデータベースを作成する機能をサポートしています。
もし接続文字列がディスク上にまだ存在していないSQL CEまたはSQL Server Expressデータベース・ファイルをポイントしている場合、これはデフォルトで行われます。これを行うために、手動でのステップを行う必要はありません。
この実際の動きを見るには、[F5]を押してNerdDinnerアプリケーションを実行します。これによりアプリケーションのルートである“/”URLでブラウザを立ち上げます。それにより描画されるスクリーンは以下のようになります。
図18 |
アプリケーションへの“/”URLは、HomeController.Indexアクション・メソッドを実行します。これはNerdDinnerのコンテキスト・オブジェクトをインスタンス化してクエリし、すべての今後発生する夕食会をデータベースから取得します。接続文字列でポイントしているNerdDinner.sdfデータベース・ファイルはまだ存在していないので、EFコード・ファースト・ライブラリは自動的にそれを生成してくれます。これはNerdDinnerのコンテキスト・オブジェクトを使用して、生成するデータベースに対して、データベース・スキーマを自動的に推測します。
生成されたSQL CEデータベース・ファイルを見るには、Visual Studioのソリューション・エクスプローラにある“すべてのファイルを表示”アイコンをクリックしてから、“最新の情報に更新”ボタンを押して、App_Dataフォルダを展開してください。
図19 |
将来的には、(現在SQLデータベースで可能なように)VS 2010のアップデートを出荷して、“サーバ・エクスプローラ”タブ内でSQL CE 4データベースを開いて編集できるようにする予定です。これにより、簡単にデータベースのスキーマやコンテンツを閲覧(場合によっては微調整)できるようになります。それまでは、オプションとしてSQL CE 4データベース・ファイルのコンテンツを確認するために、WebMatrix内のデータベース・ツールが使えます。
NerdDinnerコンテキストとの独自の永続化マッピング・ルールは指定していませんので、生成されたデータベースはデフォルトのEFコード・ファースト名前付け規約に従いスキーマをマップします。もし独自のマッピング・ルールを指定した場合、EFコード・ファースト・ライブラリはそれを受けて、それらに合ったデータベースを生成します。
ちょっと記憶をリフレッシュするために、ここに先に定義した2つのPOCOモデル・クラスとNerdDinnerコンテキスト・クラスを示します。
図20 |
以下はアプリケーションを実行したときに追加されたテーブルで、データベースは上記のモデルに基づいて自動的に作成されています。
図21 |
“Dinners”テーブルの定義は以下のようになります。カラム名とデータ型は、自分で定義したDinnerクラスのプロパティにマップしています。DinnerIDカラムもプライマリ・キーとIDENTIFYカラムの両方として構成されました。
図22 |
“RSVPs”テーブルの定義は以下のようになります。カラム名とデータ型は、自分で定義したRSVPクラスのプロパティにマップしています。RsvpIDカラムもプライマリ・キーとIDENTIFYカラムの両方として構成されました。
図23 |
1対多のプライマリ・キー/外部キーのリレーションシップも、DinnersとRSVPsテーブル間に確立されています。EFコード・ファースト・ライブラリは、DinnerクラスがRSVPsという名前のICollection<RSVP>プロパティを持っていて、RSVPクラスはDinnerプロパティを持っているため、これは確立されるべきだと推測します。
■いくつかの夕食会とデータベースをひも付け
ではいくつかの夕食会を作成して、データベースに追加してみましょう。まずホームページ上の“Create New Dinner”リンクをクリックして、“Create”フォームに移ります。
図24 |
“Create”ボタンをクリックすると、新しい夕食会がデータベースに保存されます。これを複数回繰り返して、異なるいくつかの夕食会を登録します。作成した新しい各夕食会はデータベースに保存され、ホームに今後開催される夕食会リストに表示されます。
図25 |
ステップ5:モデルの変更
アプリケーションが成長するに従い、継続的にモデルを進化させ、リファクタリングしていきましょう。EFのコード・オンリーのライブラリにはいくつかの素晴らしい開発機能があり、それにより開発用データベースでこの進化を簡単に調整できます。
■Dinnerモデルへ新しいプロパティを追加
Dinnerクラスへの簡単な変更をウォークスルーしてみましょう。具体的には“Country”という名前のプロパティをDinnerクラスに追加します。
図26 |
変更が完了したので、Visual Studioで[F5]キーを押してアプリケーションを再実行してみましょう。これを行うと、以下のようなエラー・メッセージが表示されます。
図27 |
Dinnerクラスの構成を変更し、もはやモデル・オブジェクトがデータベースに自動作成された“Dinners”テーブルと同じ形ではないので、このエラー・メッセージが発生します。
EFが自動的にデータベースを作成するとき、デフォルトで“EdmMetadata”テーブルをデータベースへ追加することによって、データベース・スキーマを自動的に作成するのに使用したモデル・オブジェクトの形を追跡します。
図28 |
モデル・オブジェクトに変更が加わり、それがデータベースと同期できないことをEFが検知したとき、上記のエラー・メッセージが発生します。
■データベースとモデル・クラスの再同期
モデル・オブジェクトとデータベースを“再同期”する方法はいくつかあります。
- 手動でデータベース・スキーマを更新してモデルに一致させる。
- データベース・ファイルを手動で削除してアプリケーションを再実行し、EFに自動的にデータベースを再作成させる。
- モデルを変更したときに自動的にデータベースを更新するEFコード・ファーストの機能を有効にする。
この最後の自動オプションをNerdDinnerアプリケーションでどのように使用するかを見てみましょう。
■RecreateDatabaseIfModelChanges機能
EFコード・ファースト・ライブラリのCTP 4には便利な開発時機能があり、モデル・クラスを修正したときに、データベースを自動で再作成できます。それを有効にすると、データベース自動作成で使用したモデル・クラスが変更されたのをEFが確認し、新しいモデル・クラスの形とデータベースが合うように再作成します。これを行うために手動のステップを行う必要はありません。
この機能は、アプリケーションを初めて開発するときに、特に便利です。なぜなら、毎回データベース・スキーマを同期するための手動作業をする必要なく、簡単にモデル・コードのリファクタリングや再構築を行うことのできる自由と柔軟性が得られるからです。特にSQL CEとうまく動作します。これはファイル・ベースのデータベースであるため、その場で1秒以内にドロップし再作成できるからです。これは信じられないほどスムーズな開発ワークフローを可能にします。
この機能を有効にする一番簡単な方法は、Global.asaxクラス内のApplication_Startイベント・ハンドラにDatabase.SetInitializerの呼び出しを追加することです。
図29 |
これはモデル・クラスが形を変えたときに、NerdDinnerモデルとNerdDinners.sdfデータベースが一致するように、EFに再作成せよと伝えます。いまアプリケーションを再実行すると、モデル・クラスとデータベースが同期できないというエラー・メッセージは、もう表示されません。EFは自動的にデータベースを再作成して新しいモデル・クラスの形に一致させるので、アプリケーションは正しく実行されます。
図30 |
■自動作成されたデータベースへの初回データ設定
上記のスクリーンショットで気付かれるかもしれませんが、データベースを再作成したときに夕食会のデータは失われました。これは自動の“RecreateDatabaseIfModelChanges”の動作が、既存データを1つのスキーマから別のところへ“マイグレート”したいという本番シナリオを目的としていないからです。
注:本番データで作業していて、スキーマのバージョン付けを行いたいというシナリオに対して、よりよいデータ・マイグレーションのサポートを提供するために、これとは別の作業をわれわれは行っています。それは、ここで述べている初期開発時の機能とは異なるシナリオであると考えています。そのようなデータ・マイグレーション機能は、今回のCTPでは有効になりません。
EFはデータベースが作成/再作成されたときに、生成されたデータベースにデフォルト/テスト・データを“流し込む”ための機能をオプションでサポートしています。この機能が非常に便利だと思っています。それは手動で多くのテスト・データを入力する必要なく、モデルをリファクタリング可能にし、簡単にアプリケーションを実行してシナリオを試行できるからです。
以下のような“NerdDinnersIntializer”クラスを書けば、データベースのデータをNerdDinnerに“流し込む”ことができます。これにより、2つの“夕食会サンプル”を作成し、それらをデータベースに追加しています。
図31 |
Global.asaxに追加したDatabase.Initializerメソッド呼び出しを更新して、この“NerdDinnersInitializer”クラスを開始時に使用できます。
図32 |
以降は、NerdDinnerモデル・クラスのいずれかを変更すると、データベースは自動的にモデルに一致するようにドロップされ再作成され、そしてすでにデータベースには、テスト用に挿入している2つの夕食会が入っています。
図33 |
■簡単なリファクタリング
上記の機能により、開発時のコードを非常に簡単に発展させ、リファクタリングすることができます。コード変更に伴い、手動でデータベースの同期を行うためにツールを使用したり、スクリプトを実行したりする必要はありません。
モデル・クラス、LINQ式、テスト・データの“流し込み”はすべて強く型付けされているので、Visual Studio内でリファクタリング・ツールのサポートを活用して、素早く簡単な方法で、自動的にコードへ変更を適用することもできます。
ステップ6:検証ルールの追加
素晴らしく、かつシンプルなデータ入力アプリケーションが構築できました。
ただし問題が1つあり、Create Dinnerフォーム内でフィールドが正確に入力されたことを確証するための入力検証が現在何も設定されていません。それを修正しましょう。
■DataAnnotationsを使用して検証を追加
ASP.NET MVCベースのアプリケーションの検証ルールは通常、モデル内でも、最もよく使用されるものです。このため、1つの場所でそれらを保守でき、それと対応するいくつのコントローラやビューで実施できます。ASP.NET MVCはさまざまな異なるメカニズムを使用して検証ルールを実装でき、使用したい検証ルールをほぼ何でもサポートできるくらい柔軟性があります。
ASP.NET MVC 2には、.NETの検証ルールであるSystem.ComponentModel.DataAnnotationsライブラリを使用するビルトイン・サポートがあります。これにより、検証属性を使用して、モデル・クラスへ検証ルールを宣言的に適用できます。この機能についての詳細は、以前書いたブログ投稿で確認できます。この方法を活用して、NerdDinnerアプリケーションの入力検証を有効にします。
先に定義したDinnerクラスに戻って、いくつかの検証属性をプロパティに追加しましょう(注:“using System.ComponentModel.DataAnnotations”名前空間も追加する必要があります)。
図34 |
[Required]検証属性は、特定のプロパティを指定しなければならないことを示しています。[StringLength]検証属性では、特定の文字列プロパティに対する最大の長さが示せます。[RegularExpression]検証属性では、特定の文字列プロパティが、指定された正規表現に一致しなければ有効にならないことを示せます。この場合では、電子メール・アドレスです。
各検証属性は“ErrorMessage”プロパティをサポートしており、検証が失敗すると表示されるエラー・メッセージを指定できます。これは(上記のように)文字列としてハードコーディングすることも、リソースから引っ張ってくることもでき、簡単にローカライズできます。
■いくつかのCSSとJavaScriptファイルの参照
最後のステップは、Create.aspxビュー・テンプレートに戻って、プロジェクトにあるSite.cssファイルへの<link>参照と、2つのJavaScriptファイルを参照する2つの<script>要素を追加します。<form>要素が描画される前にHtml.EnableClientValidationメソッドを呼び出す1行のコードも追加します。
図35 |
これらの変更により、(より視覚的になるように)そのページに表示されるすべての検証エラー・メッセージがスタイル化されることと、モデルに適用する検証ルールがクライアントとサーバの両方に適用されることを確実にします。
■アプリケーションの実行
アプリケーションを再実行して新しい夕食会を作成してみましょう。まず何の値も入力せずに“Create”ボタンを押してみましょう。モデルに適用した検証エラー・メッセージがブラウザに表示されているのを確認できます。
図36 |
ASP.NET MVCでクライアント側の検証を有効にできるので(上記で書いた1行のコードです)、エラー・メッセージはリアルタイムで更新され、変更されます。
図37 |
“Title”が20文字以上になったときの検証エラー・メッセージがどのように変更されるかを確認してください。これはDinner.Titleプロパティ上の[StringLength]プロパティが最大20文字を許可していることを示しているためです。同じように、“HostedBy”テキストボックス内に値を入力すると、エラー・メッセージは“[Requred]”エラー・メッセージ(電子メール・アドレスの入力を促すもの)から“[RegularExpression]”エラー・メッセージ(有効な電子メール・アドレスではないことを告げるもの)に変化します。
(JavaScript検証を通らないようにしてプロテクトしようとしても)これらの検証ルールはブラウザ内(JavaScript経由)およびサーバ上の両方で動作します。コントローラ・クラスに何の変更も行う必要はありません。これらのルールを一度モデル内で指定すれば、あらゆる場所へ適用できるという機能は非常に強力です。そして、これは非常にクリーンな方法であり、アプリケーションを継続して進化させることが可能になります。
これらのASP.NET MVC 2のモデル検証機能と動作方法についての詳細は、ここで確認できます。
ダウンロード
ここをクリックすると、このブログ投稿で構築した上記のNerdDinnerReloadedサンプルをダウンロードして実行できます。これにはVS 2010(または無償のVisual Web Developer 2010 Express)が必要です。
重要:上記のサンプルを動作させるためには、マシン上にSQL CE 4をダウンロードしてインストールしなければなりません。EFコード・ファースト・ライブラリはここでダウンロードできます。これらのダウンロードは、いずれもマシンに影響しません。
まとめ
“EFコード・ファースト”機能の今週のCTP 4リリースは、データを扱う際ための非常に素晴らしいコード中心の方法を提供します。これはより多くの生産性と多くのパワーをもたらします。今回のチュートリアルでは、CTP 4リリースで提供される新しい生産性の改善点のいくつかに、最もフォーカスしました。独自の永続化マッピング・ルールを有効にする流れるようなAPI(Fluent API)、改善されたテスト性のサポート、そのほか、より高度な機能などを含む、掘り下げるべきシナリオはまだまだあります。
今回のEFコード・ファーストのCTP 4リリースはここからダウンロードできます。“EFコード・ファースト”についての詳細は、ADO.NETチームの以下のブログ投稿で確認してください。
- EF CTP4のアナウンスのブログ投稿
- EF CTP4生産性改善のブログ投稿
- EF CTP4コード・ファースト・ウォークスルーのブログ投稿
- DataAnnotationsとコード・ファースト
- コード・ファーストにおけるデフォルトの規約
- Scott HanselmanのCTP4についてのウォークスルー投稿
Hope this helps,
Scott
P.S. ブログに加え、現在Twitterを使って簡単な更新やリンク共有を行っています。twitter.com/scottguで、わたしをフォローしてください。
「〜ScottGu氏のブログより〜」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|