(23)ASP.NET Core EF関係データベースモデリング

25487 ワード

1.概要


一般的に、このセクションの構成はリレーショナル・データベースに適用されます.リレーショナル・データベース・プロバイダをインストールすると、ここに表示される拡張方法が使用可能になります(Microsoft.EntityFrameworkCore.Relationalパッケージが共有されているため).

2.テーブルマッピング


テーブル・マッピングは、データベース内のどのテーブルがコンテンツ・クエリーおよび保存操作を行うべきかを示します.

2.1約定


各エンティティは、DbSetプロパティ(派生コンテキスト内のエンティティを公開)と同じ名前のテーブルにマッピングされるように設定されます.指定されたDbSetエンティティに含まれていない場合は、クラス名が使用されます.

2.2データ注釈


データ・コメントを使用して、タイプ・マッピング・テーブルを構成できます.
[Table("blogs")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

テーブルが属するアーキテクチャ(データベース)を指定することもできます.
[Table("blogs", Schema = "blogging")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

2.3Fluent API


よく知られているAPIを使用して、タイプがマッピングされたテーブルを構成できます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .ToTable("blogs");
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

テーブルが属するアーキテクチャ(データベース)を指定することもできます.
modelBuilder.Entity().ToTable("blogs", schema: "blogging");

3.カラムマッピング


カラム・マッピングは、データベース内でクエリーおよび保存するカラム・データを識別します.

3.1約定


各アトリビュートは、アトリビュートと同じ名前のカラムにマッピングされるように設定されます.

3.2データ注釈


データ・コメントを使用して、属性がマッピングされた列を構成できます.
namespace EFModeling.DataAnnotations.Relational.Column
{
    class MyContext : DbContext
    {
        public DbSet Blogs { get; set; }
    }
    public class Blog
    {
        [Column("blog_id")]
        public int BlogId { get; set; }
        public string Url { get; set; }
    }
}

3.3Fluent API


よく知られているAPIを使用して、属性がマッピングされたカラムを構成できます.
namespace EFModeling.FluentAPI.Relational.Column
{
    class MyContext : DbContext
    {
        public DbSet Blogs { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity()
                .Property(b => b.BlogId)
                .HasColumnName("blog_id");
        }
    }
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
    }
}

4.データ型


データ型とは、属性がマッピングされたカラムのデータベース固有のタイプです.

4.1約定


約束に従って、データベースプロバイダは属性に基づいている.NETタイプデータ型を選択します.また、構成の最大長、プロパティがプライマリ・キーの一部であるかどうかなど、他のメタデータも考慮されます.たとえば、SQL ServerのDateTime、nvarchar(max)がキーのプロパティとして使用されます.

4.2データ注釈


データ・コメントを使用して、カラムの正確なデータ型を指定できます.たとえば、次のコードは、Urlを最大200長の非unicode文字列に構成します.Ratingは5〜2小数位である.
public class Blog
{
    public int BlogId { get; set; }
    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }
    [Column(TypeName = "decimal(5, 2)")]
    public decimal Rating { get; set; }
}

4.3Fluent API


また、よく知られているAPIを使用して、カラムに同じデータ型を指定することもできます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity(eb =>
        {
            eb.Property(b => b.Url).HasColumnType("varchar(200)");
            eb.Property(b => b.Rating).HasColumnType("decimal(5, 2)");
        });
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public decimal Rating { get; set; }
}

5.プライマリ・キー


エンティティタイプごとのキーにprimary key(プライマリキー)コンストレイントを導入します.

5.1約束


データベース内のプライマリ・キーは、ルールに従ってPK_と名前が付けられます.

5.2データ注釈


データ・コメントを使用して、プライマリ・キーのリレーショナル・データベースの特定の側面を構成することはできません.

5.3Fluent API


APIを使用して、primary key(プライマリ・キー)制約の名前をデータベースに構成できます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .HasKey(b => b.BlogId)
            .HasName("PrimaryKey_BlogId");
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

6.デフォルトアーキテクチャ


オブジェクトに明示的にスキーマを構成していない場合は、デフォルトのスキーマはオブジェクトが作成されるデータベース・スキーマです.

6.1約束


約束に従って、データベース・プロバイダは最適なデフォルト・アーキテクチャを選択します.たとえば、Microsoft SQLサーバではdboアーキテクチャが使用され、sqliteではアーキテクチャがサポートされていないため、sqliteではアーキテクチャが使用されません.

6.2データ注釈


データ・コメントを使用してデフォルト・アーキテクチャを設定できません.

6.3Fluent API


APIを使用してデフォルトのアーキテクチャを指定できます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("blogging");
    }
}

7.デフォルト


新しいローが挿入され、カラムに値が指定されていない場合、カラムのデフォルト値は挿入する値です.

7.1約定


既定値は設定されていません.

7.2データ注釈


データ・コメントを使用してデフォルト値を設定できません.

7.3Fluent API


APIを使用して、プロパティのデフォルト値を指定できます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .Property(b => b.Rating)
            .HasDefaultValue(3);
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public int Rating { get; set; }
}

デフォルト値の計算に使用するSQLクリップも指定できます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .Property(b => b.Created)
            .HasDefaultValueSql("getdate()");
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public DateTime Created { get; set; }
}

8.インデックス(リレーショナル・データベース)


リレーショナル・データベースのインデックスは、エンティティ・フレームワークのコアのインデックスと同じ概念にマッピングされます.

8.1約定


規則に従って、インデックスの名前はIX__です.複合インデックスの場合は、次の線で区切られたプロパティ名のリストになります.

8.2データ注釈


データ・コメントを使用してインデックスを構成できません.

8.3Fluent API


よく知られているAPIを使用して、インデックスの名前を構成できます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .HasIndex(b => b.Url)
            .HasName("Index_Url");
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

フィルタを指定することもできます.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .HasIndex(b => b.Url)
            .HasFilter("[Url] IS NOT NULL");
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

SQL ServerプロバイダEFを使用して、nullの列に対して一意のインデックスに含まれるすべてのIS NOT NULLフィルタを追加します.この約束を書き換えるにはnullに値を指定します.
class MyContext : DbContext
{
    public DbSet Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .HasIndex(b => b.Url)
            .IsUnique()
            .HasFilter(null);
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

SQL Serverインデックスにカラムが含まれています.クエリ内のすべてのカラムがキー列または非キー列としてインデックスに含まれている場合、カラムを含めてインデックスを構成することで、クエリのパフォーマンスを大幅に向上させることができます.
class MyContext : DbContext
{
    public DbSet Posts { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .HasIndex(p => p.Url)
            .IncludeProperties(p => new
            {
                p.Title,
                p.PublishedOn
            })
            .HasName("Index_Url_Include_Title_PublishedOn");
    }
}
public class Post
{
    public int PostId { get; set; }
    public string Url { get; set; }
    public string Title { get; set; }
    public DateTime PublishedOn { get; set; }
}

参考文献:テーブルマッピングカラムマッピングデータ型プライマリ・キーデフォルト・アーキテクチャデフォルト値インデックス(リレーショナル・データベース)