リレーションシップの概要

このドキュメントでは、オブジェクト モデルとリレーショナル データベースのリレーションシップの表現の簡単な概要について説明します。この 2 つの間で EF Core がどのようにマップされるかを含みます。

オブジェクト モデルのリレーションシップ

リレーションシップは、2 つのエンティティが互いを関連付ける方法を定義します。 たとえば、ブログの投稿をモデル化する場合、各投稿は公開されているブログに関連し、ブログはそのブログに公開されているすべての投稿に関連します。

C# のようなオブジェクト指向言語では、ブログと投稿は通常、 と Postの 2 つのクラスBlogで表されます。 次に例を示します。

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }
}
public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }
}

上記のクラスでは、 と Post が関連していることを示すものBlogはありません。 これは、発行先の への参照PostBlogを追加することで、オブジェクト モデルに追加できます。

public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateOnly PublishedOn { get; set; }
    public bool Archived { get; set; }

    public Blog Blog { get; set; }
}

同様に、同じリレーションシップの反対方向は、 の各 BlogオブジェクトのPostコレクションとして表すことができます。

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}

この接続はBlogPost、逆にPostBlog、EF Core では "リレーションシップ" と呼ばれます。

重要

通常、 1 つの リレーションシップはどちらの方向でも走査できます。 この例では、 プロパティBlogを使用して から、 Post プロパティPostBlog.Posts使用して Post.Blog に戻りますBlog。 これは 1 つの リレーションシップであり、2 つではありません。

ヒント

EF Core では、 Blog.Posts プロパティと Post.Blog プロパティは "ナビゲーション" と呼ばれます。

リレーショナル データベースのリレーションシップ

リレーショナル データベースは、外部キーを使用するリレーションシップを表します。 たとえば、SQL ServerまたはAzure SQLを使用すると、次の表を使用して クラスPostBlog クラスを表すことができます。

CREATE TABLE [Posts] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Content] nvarchar(max) NULL,
    [PublishedOn] datetime2 NOT NULL,
    [Archived] bit NOT NULL,
    [BlogId] int NOT NULL,
    CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE);

CREATE TABLE [Blogs] (
    [Id] int NOT NULL IDENTITY,
    [Name] nvarchar(max) NULL,
    [SiteUri] nvarchar(max) NULL,
    CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]));

このリレーショナル モデルでは、 Posts テーブルと Blogs テーブルには、それぞれ "主キー" 列が指定されます。 主キーの値は、各投稿またはブログを一意に識別します。 さらに、テーブルには Blogs "外部キー" 列が指定されます。 Blogs主キー列Idは、テーブルのBlogId外部キー列Postsによって参照されます。 この列は、 の列の値が の列PostsBlogIdIdBlogsと一致するように "制約付き" です。 この一致により、すべての投稿が関連するブログが決まります。 たとえば、テーブルの BlogId 1 行の Posts 値が 7 の場合、その行によって表される投稿は、主キー 7 を使用してブログで公開されます。

EF Core でのリレーションシップのマッピング

EF Core リレーションシップ マッピングは、リレーショナル データベースで使用される主キー/外部キー表現を、オブジェクト モデルで使用されるオブジェクト間の参照にマッピングすることです。

最も基本的な意味では、これには次が含まれます。

  • 各エンティティ型に主キー プロパティを追加する。
  • 1 つのエンティティ型に外部キー プロパティを追加する。
  • エンティティ型間の参照を主キーと外部キーと関連付けて、単一のリレーションシップ構成を形成します。

このマッピングが行われると、EF は、オブジェクト間の参照が変更されたときに必要に応じて外部キー値を変更し、外部キー値が変更されたときに必要に応じてオブジェクト間の参照を変更します。

Note

主キーは、マッピング 関係以上に使用されます。 詳細については、「キー」を参照してください。

たとえば、上記のエンティティ型は、主キープロパティと外部キー プロパティを使用して更新できます。

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }

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

ヒント

主キー プロパティと外部キー プロパティは、エンティティ型のパブリックに表示されるプロパティである必要はありません。 ただし、プロパティが非表示の場合でも、EF モデルにまだ存在することを認識することが重要です。

Blog.Id、および の外部キー プロパティのBlog主キー プロパティは、エンティティ型Blog.Posts ( と Post.Blog) の間のPostPost.BlogId参照 ("ナビゲーション") に関連付けることができます。 これは、このような単純なリレーションシップを構築するときに EF によって自動的に行われますが、 の DbContextメソッドをオーバーライドするときにOnModelCreating明示的に指定することもできます。 次に例を示します。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(e => e.Posts)
        .WithOne(e => e.Blog)
        .HasForeignKey(e => e.BlogId)
        .HasPrincipalKey(e => e.Id);
}

これらのプロパティはすべて、 と の間 Blog の単一のリレーションシップの表現として一貫して動作します Post

詳細は以下のページをご覧ください

EF では、さまざまな種類のリレーションシップがサポートされており、これらのリレーションシップをさまざまな方法で表現および構成できます。 さまざまな種類のリレーションシップの例については、次を参照してください。

EF を初めて使用する場合は、上記の箇条書きでリンクされている例を試して、リレーションシップがどのように機能するかを確認する良い方法です。

リレーションシップ マッピングに関連するエンティティ型のプロパティを詳しく調てるには、次を参照してください。

EF モデルは、規則、マッピング属性、モデル ビルダー API という 3 つのメカニズムの組み合わせを使用して構築されます。 ほとんどの例では、モデル構築 API を示しています。 その他のオプションの詳細については、次を参照してください。

重要

モデル構築 API は、EF モデルの最終的な信頼できるソースです。常に、規則によって検出された構成またはマッピング属性によって指定された構成よりも優先されます。 EF モデルのすべての側面を構成するための完全な忠実性を備えた唯一のメカニズムでもあります。

リレーションシップに関連するその他のトピックは次のとおりです。

  • 連鎖削除。 または SaveChangesAsync の呼び出し時SaveChangesに関連エンティティを自動的に削除する方法を示します。
  • 所有されるエンティティ型 では、特別な種類の "所有" リレーションシップが使用されます。これは、ここで説明する "通常" リレーションシップよりも 2 つの型間の接続が強くなっていることを意味します。 通常のリレーションシップに関してここで説明する概念の多くは、所有リレーションシップに引き継がれている。 ただし、所有されるリレーションシップには、独自の特別な動作もあります。

ヒント

使用される用語の理解に役立つドキュメントを読む場合は、必要に応じて関係用語の 用語集 を参照してください。

リレーションシップの使用

モデルで定義されたリレーションシップは、さまざまな方法で使用できます。 次に例を示します。