Fluent API

EntityFlameworkを使うときに、データベース側の設定を指定するのに使う。

具体的には、DbContextから継承したクラスでOnModelCreatingをオーバーライドする。baseは最後に行うこと。

テーブルの名前を変える

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Course>().ToTable("tbl_Course");
}

主キー

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Book>().HasKey(t => t.ISBN);
}

コンポジットキー

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<OrderItem>().HasKey(t => new { t.OrderId, t.OrderItemId});
}

カラムの名前

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Course>().Property(t => t.Name).HasColumnName("sName");
}

カラムのタイプ

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Course>().Property(t => t.Name).HasColumnType("varchar");
}

カラムの順番

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Course>().Property(t => t.Name).HasColumnOrder(2);
}

Nullable

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Course>().Property(t => t.Name).IsRequires();
}

文字の長さ

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Course>().Property(t => t.Name).HasMaxLength(255);
}

1 to * の関係

Authorはいくつものコースを持ってて、Courseは一つだけAuthorを持つ関係

cascadeOnDeleteは親表でdeleteしたときに子表で対応する行を削除しないため(デフォルトはtrue)に行う

modelBuilder.Entity<Author>().HasMany(a => a.Courses).WithRequired(c => c.Author).HasForeignKey(c => c.AuthorId).WillCascadeOnDelete(false)

* to *の関係

Courseは複数のタグを持ってて、タグは複数のCourseに紐づいている関係、で中間の名前をCourseTagsにしたい。そして、中間テーブルのキーの名前を指定したい。

modelBuilder.Entity<Course>().HasMany(c => c.Tags).WithMany(t => t.Courses).Map(m => 
{
    m.ToTable("CourseTags");
    m.MapLeftKey("CourseId");
    m.MapRightKey("TagId");
)

1 to 0/1の関係

modelBuilder.Entry<Course>().HasOptional(c => c.Caption).WithRequired(c => c.Course)

1 to 1の関係

どっちが親なのかわからなくなるので、処理しないとadd-migrationでエラー。

modelBuilder.Entry<Course>().HasRequired(c => c.Cover).WithRequiredPrincipal(c => c.Course)

データベースに反映させる

add-migrationでデータベースに反映させる

PM> add-migration InitialModel -force

Configurationを別ファイルにする

OnModelCreatingに全部を書くのは、毎回modelBuilder.Entry<Course>から書くのが大変。で、別ファイルにするには

protected overrid void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new CourseConfiguration());
}

として、EntityConfigurationsフォルダを作り、CourseConfiguration.csを作成

public class CourseConfiguration : EntityTypeConfiguration<Course>
{
    public CourseConfiguration()
    {
        ToTable("CourseTable");
        Property(c => c.Description).IsRequired();
    }
}

のように記載することでちょっと整理できるかも。