連載:Entity Framework 4.1入門

第2回 EF 4.1の規約とデータベースの初期化方法

WINGSプロジェクト 土井 毅(監修:山田 祥寛)
2011/07/13
Page1 Page2 Page3

 前回はEF 4.1の簡単なサンプルを構築することで、コード・ファーストによるアプリケーション開発が非常に簡潔なコードになることを確認できた。特に、「設定に勝る規約(Convention over Configuration:CoC)」の考え方に基づいて、設定ファイルの記述がほとんど必要なくなることが特徴だった。

 今回は、コード・ファーストの規約を中心に、細かなカスタマイズ方法も含めて解説していく。

[コラム]EF 4.1言語パックのリリース

 2011年7月8日に日本語のサポートを含む「EF 4.1言語パック」がリリースされた。言語パックには、EF 4.1の、翻訳されたリソース(ドキュメントやエラー・メッセージなど)が含まれており、インストールすることで、Visual StudioのIntelliSenseでも日本語の情報が表示されるようになる。言語パックは、以下のリンク先からダウンロードできる。

Entity Framework 4.1の規約とカスタマイズ方法

 前回、コード・ファーストで使用されるいくつかの規約について解説したが、ここで主な規約を列挙してみよう。それぞれ、属性を用いて規約外の設定を行う方法についても記すので、参考にしてほしい。ここで紹介する属性はすべてSystem.ComponentModel.DataAnnotations名前空間に属している。

 なお、この名前空間にはEF 3.5、EF 4から存在する属性と、EF 4.1から導入された属性が混在しており、すべての属性を使用するためには図1のように、System.ComponentModel.DataAnnotationsアセンブリへの参照を追加する必要がある(EF 4.1の属性のみであれば、前回追加したEntity Frameworkアセンブリの参照のみでよいが、EF 4以前の属性を使用する際には、System.ComponentModel.DataAnnotationsアセンブリへの参照が必要)。

図1 System.ComponentModel.DataAnnotationsアセンブリへの参照の追加

接続文字列、データベース名

 デフォルトでは、アプリケーション設定ファイルで定義された接続文字列のうち、コンテキスト・クラスと同じ名前のものが使用される。接続名が存在しない場合は、コンテキスト・クラスの完全修飾名(名前空間を含むクラス名)と同じ名前のデータベースを、ローカルのSQL Server Express上に作成して接続する。

 このルールを変更するには、基底クラスDbContextのコンストラクタに以下のように指定すればよい。

public class ItemCatalog : DbContext
{
  // 接続名の明示的な指定
  public ItemCatalog()
  : base("ItemDB") { }
……省略……
Public Class ItemCatalog
    Inherits DbContext

  Public Sub New()
    ' 接続名の明示的な指定
    MyBase.New("ItemDB")
  End Sub
……省略……
リスト1 使用する接続文字列の指定(上:ItemCatalog.cs、下:ItemCatalog.vb)

 なお、今回はSQL Server Compact 4.0上にデータを作成するため、App.configファイルに「ItemDB」という名前の接続文字列を定義しておく(リスト2)。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
  <add name="ItemDB"
    connectionString="Data Source=|DataDirectory|SampleDatabase.sdf"
    providerName="System.Data.SqlServerCe.4.0"/>
  </connectionStrings>
</configuration>
リスト2 接続文字列の定義(App.config)

テーブル名

 デフォルトではエンティティ・クラス名の(英語の)複数形がテーブル名にマッピングされる。ただし、日本語などが含まれている場合は、複数形化せず、クラス名がそのままテーブル名になる。

 リスト3は「住所」という名前のエンティティ・クラスを定義した例である。そのままでは複数形化せず、「住所」という名前のテーブルが作成されるが、Table属性を付加することで、明示的にエンティティ・クラスと関連するテーブルの名前を指定できる。

// 明示的にテーブル名を指定
[Table("T_Addresses")]
public class 住所
{

……省略……
' 明示的にテーブル名を指定
<Table("T_Addresses")>
Public Class 住所

……省略……
リスト3 Table属性で明示的にテーブル名を指定(上:住所.cs、下:住所.vb)

フィールド名

 デフォルトではエンティティ・クラスのプロパティがテーブルの同名のフィールドに、プロパティの型がデータ型にマッピングされる。

 もしも明示的にフィールド名を指定したいならば、リスト4のようにフィールドにColumn属性を付加すればよい。また、Column属性のTypeNameプロパティでは、プロパティのデータ型を指定できる。このプロパティには、データベース依存のデータ型(例えば文字列を表す「nvarchar」)を指定している。

public class 住所
{

  // データベース上のフィールド名とデータ型を指定
  [Column("Zipcode", TypeName="nvarchar")]
  public string 郵便番号 { get; set; }

……省略……
Public Class 住所

  ' データベース上のフィールド名とデータ型を指定
  <Column("Zipcode", TypeName:="nvarchar")> *1
  Public Property 郵便番号 As String

……省略……
リスト5 Column属性でフィールド名とデータ型を指定(上:住所.cs、下:住所.vb)

*1  「:=」という表記はなじみが薄いかもしれないが、VB(Visual Basic)で属性の名前付き引数を指定するための記法である。

主キー

 デフォルトでは、「ID」あるいは「<クラス名>ID」という名前のプロパティ(大文字小文字は無視)が主キー・プロパティと見なされる。さらに主キー・プロパティがint/long/short型の場合は自動採番のフィールドになる(SQLの「IDENTITY」に対応)。

 しかし、リスト6のようにKey属性を使用することで、上記の命名則に沿わないプロパティを主キー・プロパティに設定することもできる。

public class 住所
{
  // 「Id」「住所Id」ではない「JushoId」を主キーに指定
  [Key]
  public int JushoId{ get; set; }

……省略……
Public Class 住所

  ' 「Id」「住所Id」ではない「JushoId」を主キーに指定
  <Key()>
  Public Property JushoId As Integer

……省略……
リスト6 Key属性による主キーの指定(上:住所.cs、下:住所.vb)

 またコード・ファーストでは、複合主キーにも対応しており、リスト7のように、Key属性とColumn属性のOrderプロパティを併用することで、複合主キーを定義できる。ここでは整数型のKey1プロパティと文字列型のKey2プロパティで複合主キーを定義し、それぞれOrderプロパティで主キーの順番を指定している。

public class CompositeKeyEntity
{
  // 複合キー1つ目
  [Key, Column(Order = 0)]
  public int Key1{get;set;}

  // 複合キー2つ目
  [Key, Column(Order = 1)]
  public string Key2 { get; set; }

  public string Data { get; set; }
}
Public Class CompositeKeyEntity

  ' 複合キー1つ目
  <Key(), Column(Order:=0)>
  Public Property Key1 As Integer

  ' 複合キー2つ
  <Key(), Column(Order:=1)>
  Public Property Key2 As String

  Public Property Data As String

End Class
リスト7 複合キーの指定例(上:CompositeKeyEntity.cs、下:CompositeKeyEntity.vb)

 実際のデータベース上では、図2のようにKey1とKey2が複合キー(図中ではそれぞれ「PK」と表記)になる。

図2 複合キーの例

 なお、コード・ファーストにおいても複合主キーはサポートされているものの、検索時に扱うデータ量の削減、および、ほかのテーブルから外部キーで参照する場合の構造をシンプルにするため、可能であれば別個に人工キー*2などを設けて主キーを割り当てるのが望ましいだろう。

*2 レコードごとに割り当てられる連番の整数値など、キーとしての役割のみを持つフィールドのこと。

フィールドのNULL許容

 Nullable型のプロパティの場合はNULL許容フィールドにマッピングされる。それ以外はNULLを許容しないフィールドになる(SQLの「NOT NULL」に対応)。


 INDEX
  [連載]Entity Framework 4.1入門
  第2回 EF 4.1の規約とデータベースの初期化方法
  1.Entity Framework 4.1の規約とカスタマイズ方法(1)
    2.Entity Framework 4.1の規約とカスタマイズ方法(2)
    3.データベースの初期化

インデックス・ページヘ  「連載:Entity Framework 4.1入門」


Insider.NET フォーラム 新着記事
  • 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間