関係Relationships

リレーションシップを定義する方法の 2 つのエンティティ互いに関連します。A relationship defines how two entities relate to each other. リレーショナル データベース、これは、外部キー制約で表されます。In a relational database, this is represented by a foreign key constraint.

注意

この記事のサンプルの大部分では、一対多のリレーションシップを使用して、概念を示します。Most of the samples in this article use a one-to-many relationship to demonstrate concepts. 一対一および多対多のリレーションシップの例については、その他のリレーションシップのパターン記事の最後のセクションです。For examples of one-to-one and many-to-many relationships see the Other Relationship Patterns section at the end of the article.

用語の定義Definition of Terms

リレーションシップの記述に使用される用語の数があります。There are a number of terms used to describe relationships

  • 依存エンティティ:これは、外部キー プロパティを含むエンティティです。Dependent entity: This is the entity that contains the foreign key property(s). リレーションシップの 'child' と呼ばれることがあります。Sometimes referred to as the 'child' of the relationship.

  • プリンシパル エンティティ:これは、プライマリ/代替のキー プロパティを含むエンティティです。Principal entity: This is the entity that contains the primary/alternate key property(s). リレーションシップの 'parent' と呼ばれることがあります。Sometimes referred to as the 'parent' of the relationship.

  • 外部キー:エンティティに関連するプリンシパル キー プロパティの値を格納するために使用される、依存エンティティのプロパティです。Foreign key: The property(s) in the dependent entity that is used to store the values of the principal key property that the entity is related to.

  • プリンシパル キー:プリンシパル エンティティを一意に識別するプロパティです。Principal key: The property(s) that uniquely identifies the principal entity. 主キーや代替キーがあります。This may be the primary key or an alternate key.

  • ナビゲーション プロパティ。関連会計主体への参照を格納しているプリンシパルや依存するエンティティで定義されたプロパティ。Navigation property: A property defined on the principal and/or dependent entity that contains a reference(s) to the related entity(s).

    • コレクション ナビゲーション プロパティ。を多くの関連エンティティへの参照を含むナビゲーション プロパティ。Collection navigation property: A navigation property that contains references to many related entities.

    • ナビゲーション プロパティの参照: 1 つの関連するエンティティへの参照を保持するナビゲーション プロパティ。Reference navigation property: A navigation property that holds a reference to a single related entity.

    • 逆ナビゲーション プロパティ。特定のナビゲーション プロパティを検討する場合、リレーションシップのもう一方の端のナビゲーション プロパティに関係する用語です。Inverse navigation property: When discussing a particular navigation property, this term refers to the navigation property on the other end of the relationship.

次のコード リストは、一対多関係を示していますBlogと。PostThe following code listing shows a one-to-many relationship between Blog and Post

  • Post依存エンティティは、します。Post is the dependent entity

  • Blogプリンシパル エンティティにはBlog is the principal entity

  • Post.BlogId外部キーです。Post.BlogId is the foreign key

  • Blog.BlogId(この場合は代替キーではなく、主キー)、プリンシパル キーにはBlog.BlogId is the principal key (in this case it is a primary key rather than an alternate key)

  • Post.Blog参照ナビゲーション プロパティは、します。Post.Blog is a reference navigation property

  • Blog.Postsコレクション ナビゲーション プロパティは、します。Blog.Posts is a collection navigation property

  • Post.Blog逆ナビゲーション プロパティは、 Blog.Posts (その逆)Post.Blog is the inverse navigation property of Blog.Posts (and vice versa)

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

規則Conventions

規則では、リレーションシップが、型上で検出されたナビゲーション プロパティがある場合に、それが作成されます。By convention, a relationship will be created when there is a navigation property discovered on a type. プロパティは、現在のデータベース プロバイダーではスカラー型として指す型がマップされないことができる場合、ナビゲーション プロパティと見なされます。A property is considered a navigation property if the type it points to can not be mapped as a scalar type by the current database provider.

注意

プリンシパル エンティティの主キー ターゲット規則によって検出されたリレーションシップに常にします。Relationships that are discovered by convention will always target the primary key of the principal entity. 代替キーをターゲットにするには Fluent API を使用して追加の構成を実行する必要があります。To target an alternate key, additional configuration must be performed using the Fluent API.

完全に定義されたリレーションシップFully Defined Relationships

リレーションシップの最も一般的なパターンでは、リレーションシップと依存するエンティティ クラスで定義されている外部キーのプロパティの両端で定義されているナビゲーション プロパティがあります。The most common pattern for relationships is to have navigation properties defined on both ends of the relationship and a foreign key property defined in the dependent entity class.

  • 2 つの型の間のナビゲーション プロパティのペアが見つかった場合が同じリレーションシップの逆ナビゲーション プロパティとして構成されます。If a pair of navigation properties is found between two types, then they will be configured as inverse navigation properties of the same relationship.

  • 依存エンティティには、という名前のプロパティが含まれている場合<primary key property name><navigation property name><primary key property name>、または<principal entity name><primary key property name>外部キーとしてように構成されます。If the dependent entity contains a property named <primary key property name>, <navigation property name><primary key property name>, or <principal entity name><primary key property name> then it will be configured as the foreign key.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

警告

2 つの型の間で定義されている複数のナビゲーション プロパティがあるかどうか (つまり互いを指すナビゲーションの 1 つ以上の個別ペア) し、リレーションシップは作成されません慣例により、および手動で構成を特定するようにする必要があります、1 組のナビゲーション プロパティ。If there are multiple navigation properties defined between two types (i.e. more than one distinct pair of navigations that point to each other), then no relationships will be created by convention and you will need to manually configure them to identify how the navigation properties pair up.

外部キー プロパティはありません。No Foreign Key Property

推奨されますが、依存エンティティ クラスで定義されている外部キー プロパティを持つ、必須ではありません。While it is recommended to have a foreign key property defined in the dependent entity class, it is not required. 外部キーのプロパティが見つからない場合シャドウ外部キーのプロパティを名前で導入される予定<navigation property name><principal key property name>(を参照してくださいプロパティをシャドウ詳細については)。If no foreign key property is found, a shadow foreign key property will be introduced with the name <navigation property name><principal key property name> (see Shadow Properties for more information).

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

単一のナビゲーション プロパティSingle Navigation Property

1 つのナビゲーション プロパティ (ありません逆のナビゲーションと外部キー プロパティはありません) を含めることは、規約によって定義されたリレーションシップが十分です。Including just one navigation property (no inverse navigation, and no foreign key property) is enough to have a relationship defined by convention. 単一のナビゲーション プロパティと外部キーのプロパティもあります。You can also have a single navigation property and a foreign key property.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

連鎖削除Cascade Delete

規則では、連鎖削除に設定されますCascadeの必要なリレーションシップとClientSetNull省略可能なリレーションシップの場合。By convention, cascade delete will be set to Cascade for required relationships and ClientSetNull for optional relationships. Cascade依存エンティティも削除することを意味します。Cascade means dependent entities are also deleted. ClientSetNullはメモリに読み込まれていない依存エンティティが維持されることを意味変更せずとする必要があります手動でまたは削除する有効なプリンシパル エンティティを指すように更新します。ClientSetNull means that dependent entities that are not loaded into memory will remain unchanged and must be manually deleted, or updated to point to a valid principal entity. メモリに読み込まれているエンティティの EF コアしようと外部キー プロパティを null に設定します。For entities that are loaded into memory, EF Core will attempt to set the foreign key properties to null.

参照してください、必須および省略可能なリレーションシップ必須およびオプションの関係の違いについてのセクションです。See the Required and Optional Relationships section for the difference between required and optional relationships.

参照してください連鎖削除の詳細については、さまざまな規則が使用する既定の動作とを削除します。See Cascade Delete for more details about the different delete behaviors and the defaults used by convention.

データの注釈Data Annotations

、リレーションシップを構成するために使用する 2 つのデータの注釈がある[ForeignKey][InverseProperty]です。There are two data annotations that can be used to configure relationships, [ForeignKey] and [InverseProperty].

[ForeignKey][ForeignKey]

データ注釈を使用すると、構成するプロパティは、特定のリレーションシップの外部キー プロパティとして使用する必要があります。You can use the Data Annotations to configure which property should be used as the foreign key property for a given relationship. 外部キー プロパティは、規則によって検出されていない場合にこれは通常です。This is typically done when the foreign key property is not discovered by convention.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogForeignKey { get; set; }

    [ForeignKey("BlogForeignKey")]
    public Blog Blog { get; set; }
}

ヒント

[ForeignKey]リレーションシップのいずれかのナビゲーション プロパティに注釈を配置することができます。The [ForeignKey] annotation can be placed on either navigation property in the relationship. ナビゲーションのプロパティ、依存エンティティ クラスに移動する必要はありません。It does not need to go on the navigation property in the dependent entity class.

[InverseProperty][InverseProperty]

データ注釈を使用して、依存とプリンシパル エンティティのナビゲーション プロパティのペアを構成することができます。You can use the Data Annotations to configure how navigation properties on the dependent and principal entities pair up. 2 つのエンティティ型の間のナビゲーション プロパティの 1 つ以上のペアがある場合にこれは通常です。This is typically done when there is more than one pair of navigation properties between two entity types.

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int AuthorUserId { get; set; }
    public User Author { get; set; }

    public int ContributorUserId { get; set; }
    public User Contributor { get; set; }
}

public class User
{
    public string UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [InverseProperty("Author")]
    public List<Post> AuthoredPosts { get; set; }

    [InverseProperty("Contributor")]
    public List<Post> ContributedToPosts { get; set; }
}

Fluent APIFluent API

リレーションシップ Fluent api を構成するのには、リレーションシップを構成するナビゲーション プロパティを識別することによって開始します。To configure a relationship in the Fluent API, you start by identifying the navigation properties that make up the relationship. HasOneまたはHasManyの構成を開始するエンティティ型にナビゲーション プロパティを識別します。HasOne or HasMany identifies the navigation property on the entity type you are beginning the configuration on. 呼び出しをチェーンするWithOneまたはWithManyを逆のナビゲーションを識別します。You then chain a call to WithOne or WithMany to identify the inverse navigation. HasOne/WithOne参照ナビゲーション プロパティが使用されるとHasMany / WithManyコレクション ナビゲーション プロパティに対して使用します。HasOne/WithOne are used for reference navigation properties and HasMany/WithMany are used for collection navigation properties.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

単一のナビゲーション プロパティSingle Navigation Property

1 つのナビゲーション プロパティのみがあるかどうかは、パラメーターなしのオーバー ロードのWithOneWithManyです。If you only have one navigation property then there are parameterless overloads of WithOne and WithMany. これは、参照またはコレクションがリレーションシップのもう一方の端に概念的にが、エンティティ クラスに含まれるナビゲーション プロパティが存在しないことを示します。This indicates that there is conceptually a reference or collection on the other end of the relationship, but there is no navigation property included in the entity class.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithOne();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

外部キーForeign Key

Fluent API を使用すると、構成するプロパティは、特定のリレーションシップの外部キー プロパティとして使用する必要があります。You can use the Fluent API to configure which property should be used as the foreign key property for a given relationship.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey(p => p.BlogForeignKey);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogForeignKey { get; set; }
    public Blog Blog { get; set; }
}

次のコード リストは、複合外部キーを構成する方法を示します。The following code listing shows how to configure a composite foreign key.

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasKey(c => new { c.State, c.LicensePlate });

        modelBuilder.Entity<RecordOfSale>()
            .HasOne(s => s.Car)
            .WithMany(c => c.SaleHistory)
            .HasForeignKey(s => new { s.CarState, s.CarLicensePlate });
    }
}

public class Car
{
    public string State { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }

    public List<RecordOfSale> SaleHistory { get; set; }
}

public class RecordOfSale
{
    public int RecordOfSaleId { get; set; }
    public DateTime DateSold { get; set; }
    public decimal Price { get; set; }

    public string CarState { get; set; }
    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

文字列のオーバー ロードを使用するHasForeignKey(...)の外部キーとしてシャドウ プロパティの構成 (を参照してくださいプロパティをシャドウ詳細については)。You can use the string overload of HasForeignKey(...) to configure a shadow property as a foreign key (see Shadow Properties for more information). 以下の手順に従って)、外部キーとして使用する前に、モデルに明示的にシャドウ プロパティを追加することをお勧めします。We recommend explicitly adding the shadow property to the model before using it as a foreign key (as shown below).

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Add the shadow property to the model
        modelBuilder.Entity<Post>()
            .Property<int>("BlogForeignKey");

        // Use the shadow property as a foreign key
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey("BlogForeignKey");
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

プリンシパル キーPrincipal Key

主キー以外のプロパティを参照する外部キーにする場合は、Fluent API を使用して、リレーションシップのプリンシパル キー プロパティを構成することができます。If you want the foreign key to reference a property other than the primary key, you can use the Fluent API to configure the principal key property for the relationship. キーは、プリンシパルとして自動的に構成されているプロパティを代替キーとしてセットアップする (を参照してください代替キー詳細については)。The property that you configure as the principal key will automatically be setup as an alternate key (see Alternate Keys for more information).

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<RecordOfSale>()
            .HasOne(s => s.Car)
            .WithMany(c => c.SaleHistory)
            .HasForeignKey(s => s.CarLicensePlate)
            .HasPrincipalKey(c => c.LicensePlate);
    }
}

public class Car
{
    public int CarId { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }

    public List<RecordOfSale> SaleHistory { get; set; }
}

public class RecordOfSale
{
    public int RecordOfSaleId { get; set; }
    public DateTime DateSold { get; set; }
    public decimal Price { get; set; }

    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

次のコード リストは、複合主キーを構成する方法を示します。The following code listing shows how to configure a composite principal key.

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<RecordOfSale>()
            .HasOne(s => s.Car)
            .WithMany(c => c.SaleHistory)
            .HasForeignKey(s => new { s.CarState, s.CarLicensePlate })
            .HasPrincipalKey(c => new { c.State, c.LicensePlate });
    }
}

public class Car
{
    public int CarId { get; set; }
    public string State { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }

    public List<RecordOfSale> SaleHistory { get; set; }
}

public class RecordOfSale
{
    public int RecordOfSaleId { get; set; }
    public DateTime DateSold { get; set; }
    public decimal Price { get; set; }

    public string CarState { get; set; }
    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

警告

プリンシパル キー プロパティを指定した順序は、外部キーの指定された順序と一致する必要があります。The order in which you specify principal key properties must match the order in which they are specified for the foreign key.

必須およびオプションの関係Required and Optional Relationships

Fluent API を使用して、リレーションシップが必須またはオプションであるかどうかを構成することができます。You can use the Fluent API to configure whether the relationship is required or optional. 最終的に外部キー プロパティが必須またはオプションかどうかを制御します。Ultimately this controls whether the foreign key property is required or optional. これは、機能は、シャドウ状態の外部キーを使用しているときに最も便利です。This is most useful when you are using a shadow state foreign key. 外部キーのプロパティがエンティティ クラスであるかどうかは、リレーションシップの requiredness は外部キー プロパティが必須またはオプションかどうかに基づいて決定されます (を参照してください必須および省略可能なプロパティの詳細情報)。If you have a foreign key property in your entity class then the requiredness of the relationship is determined based on whether the foreign key property is required or optional (see Required and Optional properties for more information).

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .IsRequired();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

連鎖削除Cascade Delete

Fluent API を使用すると、特定のリレーションシップの連鎖削除の動作を明示的に構成します。You can use the Fluent API to configure the cascade delete behavior for a given relationship explicitly.

参照してください連鎖削除各オプションの詳細については、データの保存セクションでします。See Cascade Delete on the Saving Data section for a detailed discussion of each option.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int? BlogId { get; set; }
    public Blog Blog { get; set; }
}

その他のリレーションシップのパターンOther Relationship Patterns

一対一One-to-one

一対一のリレーションシップでは、両方の側で参照ナビゲーション プロパティがあります。One to one relationships have a reference navigation property on both sides. 一対多リレーションシップと同じ規則に従いますが、各プリンシパルに関連する 1 つだけの依存することを確認する外部キー プロパティに一意のインデックスが導入されました。They follow the same conventions as one-to-many relationships, but a unique index is introduced on the foreign key property to ensure only one dependent is related to each principal.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public BlogImage BlogImage { get; set; }
}

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

注意

EF は外部キーのプロパティを検出するには、その機能に基づく依存するエンティティのいずれかを選択します。EF will choose one of the entities to be the dependent based on its ability to detect a foreign key property. 従属変数として間違ったエンティティを選択した場合は、これを修正する Fluent API を使用できます。If the wrong entity is chosen as the dependent, you can use the Fluent API to correct this.

使用するリレーションシップ Fluent api を構成する場合、HasOneWithOneメソッドです。When configuring the relationship with the Fluent API, you use the HasOne and WithOne methods.

-依存エンティティの種類を指定する必要があります。 外部キーを構成するときに提供されるジェネリック パラメーターに注意してくださいHasForeignKeyの下の一覧にします。When configuring the foreign key you need to specify the dependent entity type - notice the generic parameter provided to HasForeignKey in the listing below. 一対多リレーションシップでは、オフにしている参照ナビゲーションを持つエンティティが依存するコレクションを使用して 1 つは、プリンシパルです。In a one-to-many relationship it is clear that the entity with the reference navigation is the dependent and the one with the collection is the principal. はありませんが、一対一リレーションシップのためにを明示的に定義する必要があります。But this is not so in a one-to-one relationship - hence the need to explicitly define it.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<BlogImage> BlogImages { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasOne(p => p.BlogImage)
            .WithOne(i => i.Blog)
            .HasForeignKey<BlogImage>(b => b.BlogForeignKey);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public BlogImage BlogImage { get; set; }
}

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }

    public int BlogForeignKey { get; set; }
    public Blog Blog { get; set; }
}

[多対多]Many-to-many

結合テーブルを表すエンティティ クラスを持たない多対多リレーションシップはまだサポートされていません。Many-to-many relationships without an entity class to represent the join table are not yet supported. ただし、結合テーブルとのマッピング 2 つの独立した一対多リレーションシップのエンティティ クラスを含めることによって、多対多リレーションシップを表すことができます。However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.

class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany(p => p.PostTags)
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany(t => t.PostTags)
            .HasForeignKey(pt => pt.TagId);
    }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class Tag
{
    public string TagId { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}