mvcConf @:Japan ふりかえり 2: CodeFirstでのデータベース定義の概要
CodeFirst ではクラスを定義すればそれがそのままテーブルの設計となります。
データベースにあまり強くないプログラマにとってこれはうれしいことのようですが、実際にはそうでもありません。
どのようにテーブル設計をするのがよいのかよく考えたうえでクラスの定義を行う必要があります。
ただ、そのクラス定義を必要があれば簡単に変更し、すぐにデータベースに反映していくことができる、という意味で、やはりCodeFirstはプログラマにとって大変魅力的なものとなります。
このクラス定義=テーブル設定においては、CoCの原則が適用されます。
たとえば、
- ID、またはクラス名+IDという名前のプロパティは自動的に主キーとなる
- ナビゲーションプロパティを定義すると、それにあわせてリレーションが設定される
- リレーションの相手となるクラス名+IDという名前のプロパティは外部キーとなる
- ナビゲーションプロパティに virtual を指定することでレイジーローディングが有効になる
- 文字列型のプロパティはnull許容の設定になる
- 値型のプロパティはnull否許容となる。nullable型(?をつける)とするとnull許容の設定になる
- getメソッドしかもたないプロパティ項目はデータベース上に作成されず、計算で表示される項目となる
といった規約が利用できます。
これらの規約にたいし、属性を設定することでデータベース上の設定を変更することができます。
たとえば [Required] を付加することで文字列型のプロパティでもnull否許容とすることができます。
また、[MaxLength] により、データベース上の文字の最大値を設定することができます。
属性での設定以上に細かい定義をしたい場合はFluent APIと呼ばれるAPIを利用して設定を行うことになります。
MemberクラスのNameプロパティに [Required] の設定を行うのと同じことをFluent APIで記述すると上記のようになります。
注意が必要なのは、Fluent APIを利用することでデータベース上の定義は変更することができますが、これはASP.NET MVCとしての動作にはそのままでは影響を与えない、という点です。
データベース上でName項目はnull否許容となるので、データの更新時に値が入っていなければエラーとなります。
ただし、[Required] という属性定義を利用した場合、あとで述べるASP.NET MVCのバリデーションの機能が働くため、エラーとなるまえに利用者にメッセージを表示して注意を促すことができます。
なお、Fluent APIを利用すると細かい定義を設定することが可能です。
特にすでに存在しているデータベースとPOCOクラスを関連づけたい、という場合はFluent APIを利用しないといけない場面があるでしょう。
単なるクラス定義を実際にデータベース定義に結びつけるのがDbContextを継承したクラスでのDBSet<T>型のプロパティ定義です。
テーブル名はここで指定されたプロパティの名称になりますが、プロパティ名を単数形で指定してもテーブル名は複数形になるようです。
なお、テーブル名はPOCOクラスに[Table]メソッドを付加することで指定することが可能ですし、Fluent APIを用いて指定することも可能です。
データベースを作成する場所としては、DbContextを継承したクラスの名称と同じ名称が設定されている接続文字列が探されます。
もしそのような接続文字列が存在しない場合、CodeFirstはSQL ServerのSQLExpressインスタンス(VisualStudioをインストールする際、デフォルトでSQL Server Expressのインスタンスとして作成される)の中にデータベースを作成します。
このとき作成されるデータベースの名前はnamespaceを含めたDbContextを継承したクラス名となります。
接続文字列がみつかった場合はその接続文字列に指定されている場所、名前でデータベースが作成されます。
このときSQLCe4を指定することもできます。
デフォルトではCodeFirstによるデータベースの生成は一度しか行われず、定義の変更も行われません。
このため、POCOのクラス定義を変更すると、エラーが発生します。
Initializerの基底となるクラスを変更し、アプリケーションの実行時にInitializerを設定することでこの動作を変更することができます。
Initializerの基底となることができるクラスには以下のものがあります。
- CreateDatabaseIfNotExists
- DropCreateDatabaseIfModelChanges
- DropCreateDatabaseAlways
それぞれの役割は名前のとおりです。
また、InitializerクラスのSeedメソッドをオーバーライドすることでデータベースの初期値を設定することができます。
データベースの作成時に常に同じデータをセットすることができるため、テスト環境の構築には有効だと思われます。
また、マスターデータ等初期状態で必須となるデータをデータベースに設定するのにも使えると思います。
-
2011年6月22日 5:47 午後mvcConf @:Japan のセッションビデオが公開されました « ブチザッキ