Code First 規約
Code First を使用すると、C# または Visual Basic .NET のクラスを使用してモデルを記述できます。 モデルの基本的な性質は、規約を使用して検出されます。 規約とは、Code First を使用するときに、クラス定義に基づいて概念モデルを自動的に構成する際に用いられる一連のルールです。 規約は、System.Data.Entity.ModelConfiguration.Conventions 名前空間に定義されています。
また、モデルの構成には、データ注釈または fluent API を使用することもできます。 構成には優先順位があります。最も優先順位が高いのは fluent API で、次にデータ注釈、そして規約が続きます。 詳細については、データ注釈に関する記事、「Fluent API -リレーションシップ」、Fluent API - 型とプロパティに関する記事、「VB.NET を使用した Fluent API」を参照してください。
詳細な Code First 規約の一覧は、API ドキュメントでご覧いただけます。 このトピックでは、Code First で使用される規約について概要を説明しています。
型の検出
通常、Code First の開発を使用するときはまず、概念 (ドメイン) モデルを定義する .NET Framework のクラスを記述します。 クラスを定義することに加え、モデルに含めたい型を DbContext に伝える必要があります。 そのためには、モデルに含める型の DbSet プロパティを公開する、DbContext から派生したコンテキスト クラスを定義します。 Code First は、それらの型を追加すると共に、参照されている型があればすべて取り込みます。参照されている型が別のアセンブリに定義されていたとしても同様です。
必要な型が継承階層に含まれている場合は、基底クラスの DbSet プロパティを定義するだけでかまいません。派生型が基底クラスと同じアセンブリあれば、それらが自動的に追加されます。
次の例では、SchoolEntities クラス (Departments) に DbSet プロパティが 1 つだけ定義されています。 Code First は、このプロパティを使用し、参照されているすべての型を検出して取り込みます。
public class SchoolEntities : DbContext
{
public DbSet<Department> Departments { get; set; }
}
public class Department
{
// Primary key
public int DepartmentID { get; set; }
public string Name { get; set; }
// Navigation property
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
// Primary key
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
// Foreign key
public int DepartmentID { get; set; }
// Navigation properties
public virtual Department Department { get; set; }
}
public partial class OnlineCourse : Course
{
public string URL { get; set; }
}
public partial class OnsiteCourse : Course
{
public string Location { get; set; }
public string Days { get; set; }
public System.DateTime Time { get; set; }
}
モデルから特定の型を除外したい場合は、NotMapped 属性を使用するか、または DbModelBuilder.Ignore fluent API を使用します。
modelBuilder.Ignore<Department>();
主キー規約
クラスのプロパティの名前が "ID" (大文字と小文字は区別されません) またはクラス名 + "ID" である場合、そのプロパティは Code First により主キーとして推測されます。 主キー プロパティの型が数値または GUID である場合は、ID 列として構成されます。
public class Department
{
// Primary key
public int DepartmentID { get; set; }
. . .
}
リレーションシップ規約
Entity Framework では、ナビゲーション プロパティによって、2 つのエンティティ型間のリレーションシップをナビゲートする手段が提供されます。 各オブジェクトは、参加する各リレーションシップに対してナビゲーション プロパティを持つことができます。 ナビゲーション プロパティを使用すると、リレーションシップを両方向から見て管理し、複数要素の接続性が一、またはゼロか一の場合には参照オブジェクトを返し、複数要素の接続性が多の場合にはコレクションを返すことができます。 Code First では、型に定義されているナビゲーション プロパティに基づいてリレーションシップが推測されます。
型には、ナビゲーション プロパティに加え、依存オブジェクトを表す外部キーのプロパティを追加することをお勧めします。 プリンシパル主キー プロパティとデータ型が同じで、"<ナビゲーション プロパティ名><プリンシパル主キー プロパティ名>"、"<プリンシパル クラス名><主キー プロパティ名>"、"<プリンシパル主キー プロパティ名>" のいずれかの形式に名前が該当するプロパティは、リレーションシップの外部キーを表します。 複数一致が検出された場合は、前述の優先順位が適用されます。 外部キーの検出で大文字と小文字は区別されません。 外部キーのプロパティが検出された場合、Code First は、外部キーの NULL 値の許容に基づいて、リレーションシップの複数要素の接続性を推測します。 プロパティが Null 許容の場合、リレーションシップは省略可能として登録され、それ以外の場合は、必須として登録されます。
依存エンティティの外部キーが Null 許容ではない場合、リレーションシップにカスケード削除が設定されます。 依存エンティティの外部キーが Null 許容の場合は、リレーションシップにカスケード削除は設定されません。プリンシパルが削除されたときは、外部キーが null に設定されます。 規約によって検出された複数要素の接続性とカスケード削除の動作は、fluent API を使用してオーバーライドできます。
次の例では、ナビゲーション プロパティと外部キーを使用して、Department クラスと Course クラスとの間のリレーションシップが定義されています。
public class Department
{
// Primary key
public int DepartmentID { get; set; }
public string Name { get; set; }
// Navigation property
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
// Primary key
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
// Foreign key
public int DepartmentID { get; set; }
// Navigation properties
public virtual Department Department { get; set; }
}
Note
同じ型どうしの間に複数のリレーションシップがある場合は (たとえば、Person クラスと Book クラスを定義したとき、Person クラスにはナビゲーション プロパティとして ReviewedBooks と AuthoredBooks が、また Book クラスにはナビゲーション プロパティとして Author と Reviewer があるなど)、データ注釈または fluent API を使用してリレーションシップを手動で構成する必要があります。 詳細については、データ注釈によるリレーションシップと Fluent API によるリレーションシップに関するページを参照してください。
複合型規約
主キーを推測できず、また、データ注釈と fluent API のどちらの方法でも主キーが登録されていないクラス定義が Code First によって検出された場合、その型は自動的に複合型として登録されます。 また、エンティティ型を参照するプロパティを備えていないこと、また、別の型のコレクション プロパティから参照されていないことも、複合型として検出される型の要件となります。 次のクラス定義がある場合、Details は主キーを含んでいないため、Code First によって複合型であると推測されます。
public partial class OnsiteCourse : Course
{
public OnsiteCourse()
{
Details = new Details();
}
public Details Details { get; set; }
}
public class Details
{
public System.DateTime Time { get; set; }
public string Location { get; set; }
public string Days { get; set; }
}
接続文字列規約
使用する接続を DbContext が検出する際に用いられる規約については、接続とモデルを参照してください。
規約の削除
System.Data.Entity.ModelConfiguration.Conventions 名前空間に定義されている規約は、いずれも削除することができます。 次に示したのは、PluralizingTableNameConvention を削除する例です。
public class SchoolEntities : DbContext
{
. . .
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure Code First to ignore PluralizingTableName convention
// If you keep this convention, the generated tables
// will have pluralized names.
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
カスタム規約
カスタム規約は EF6 以降でサポートされます。 詳細については、「カスタム Code First 規約」を参照してください。
.NET