ホーム > EF 4.1 Code First, mvcConf @:Japan > mvcConf @:Japan ふりかえり 2: CodeFirstでのデータベース定義の概要

mvcConf @:Japan ふりかえり 2: CodeFirstでのデータベース定義の概要

スライド5

CodeFirst ではクラスを定義すればそれがそのままテーブルの設計となります。
データベースにあまり強くないプログラマにとってこれはうれしいことのようですが、実際にはそうでもありません。
どのようにテーブル設計をするのがよいのかよく考えたうえでクラスの定義を行う必要があります。
ただ、そのクラス定義を必要があれば簡単に変更し、すぐにデータベースに反映していくことができる、という意味で、やはりCodeFirstはプログラマにとって大変魅力的なものとなります。

このクラス定義=テーブル設定においては、CoCの原則が適用されます。
たとえば、

  • ID、またはクラス名+IDという名前のプロパティは自動的に主キーとなる
  • ナビゲーションプロパティを定義すると、それにあわせてリレーションが設定される
  • リレーションの相手となるクラス名+IDという名前のプロパティは外部キーとなる
  • ナビゲーションプロパティに virtual を指定することでレイジーローディングが有効になる
  • 文字列型のプロパティはnull許容の設定になる
  • 値型のプロパティはnull否許容となる。nullable型(?をつける)とするとnull許容の設定になる
  • getメソッドしかもたないプロパティ項目はデータベース上に作成されず、計算で表示される項目となる

といった規約が利用できます。

これらの規約にたいし、属性を設定することでデータベース上の設定を変更することができます。
たとえば [Required] を付加することで文字列型のプロパティでもnull否許容とすることができます。
また、[MaxLength] により、データベース上の文字の最大値を設定することができます。

属性での設定以上に細かい定義をしたい場合はFluent APIと呼ばれるAPIを利用して設定を行うことになります。

スライド6

MemberクラスのNameプロパティに [Required] の設定を行うのと同じことをFluent APIで記述すると上記のようになります。
注意が必要なのは、Fluent APIを利用することでデータベース上の定義は変更することができますが、これはASP.NET MVCとしての動作にはそのままでは影響を与えない、という点です。
データベース上でName項目はnull否許容となるので、データの更新時に値が入っていなければエラーとなります。
ただし、[Required] という属性定義を利用した場合、あとで述べるASP.NET MVCのバリデーションの機能が働くため、エラーとなるまえに利用者にメッセージを表示して注意を促すことができます。

なお、Fluent APIを利用すると細かい定義を設定することが可能です。
特にすでに存在しているデータベースとPOCOクラスを関連づけたい、という場合はFluent APIを利用しないといけない場面があるでしょう。

スライド7

単なるクラス定義を実際にデータベース定義に結びつけるのがDbContextを継承したクラスでのDBSet<T>型のプロパティ定義です。
テーブル名はここで指定されたプロパティの名称になりますが、プロパティ名を単数形で指定してもテーブル名は複数形になるようです。
なお、テーブル名はPOCOクラスに[Table]メソッドを付加することで指定することが可能ですし、Fluent APIを用いて指定することも可能です。

スライド8

データベースを作成する場所としては、DbContextを継承したクラスの名称と同じ名称が設定されている接続文字列が探されます。
もしそのような接続文字列が存在しない場合、CodeFirstはSQL ServerのSQLExpressインスタンス(VisualStudioをインストールする際、デフォルトでSQL Server Expressのインスタンスとして作成される)の中にデータベースを作成します。
このとき作成されるデータベースの名前はnamespaceを含めたDbContextを継承したクラス名となります。

接続文字列がみつかった場合はその接続文字列に指定されている場所、名前でデータベースが作成されます。
このときSQLCe4を指定することもできます。

スライド9

デフォルトではCodeFirstによるデータベースの生成は一度しか行われず、定義の変更も行われません。
このため、POCOのクラス定義を変更すると、エラーが発生します。
Initializerの基底となるクラスを変更し、アプリケーションの実行時にInitializerを設定することでこの動作を変更することができます。

Initializerの基底となることができるクラスには以下のものがあります。

  • CreateDatabaseIfNotExists
  • DropCreateDatabaseIfModelChanges
  • DropCreateDatabaseAlways

それぞれの役割は名前のとおりです。

また、InitializerクラスのSeedメソッドをオーバーライドすることでデータベースの初期値を設定することができます。
データベースの作成時に常に同じデータをセットすることができるため、テスト環境の構築には有効だと思われます。
また、マスターデータ等初期状態で必須となるデータをデータベースに設定するのにも使えると思います。

  1. まだコメントはありません。
  1. 2011年6月22日 5:47 PM

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。