関連データの保存

分離されたエンティティに加え、モデルに定義されたリレーションシップを活用することもできます。

ヒント

この記事のサンプルは GitHub で確認できます。

新しいエンティティ グループの追加

関連するいくつかの新しいエンティティを作成しているときに、いずれかのエンティティをコンテキストに追加すると、他のエンティティも同様に追加されます。

次の例では、ブログと 3 つの関連する投稿のすべてがデータベースに挿入されます。 これらの投稿が検出され、追加されるのは、Blog.Posts ナビゲーション プロパティ経由で到達可能であるためです。

using (var context = new BloggingContext())
{
    var blog = new Blog
    {
        Url = "http://blogs.msdn.com/dotnet",
        Posts = new List<Post>
        {
            new Post { Title = "Intro to C#" },
            new Post { Title = "Intro to VB.NET" },
            new Post { Title = "Intro to F#" }
        }
    };

    context.Blogs.Add(blog);
    context.SaveChanges();
}

ヒント

単一のエンティティの状態を設定するには、EntityEntry.State プロパティを使用します。 たとえば、「 context.Entry(blog).State = EntityState.Modified 」のように入力します。

コンテキストによって既に追跡されているエンティティのナビゲーション プロパティから新しいエンティティを参照した場合、そのエンティティが検出され、データベースに挿入されます。

次の例では、データベースからフェッチされた blog エンティティの Posts プロパティに post エンティティが追加されているため、そのエンティティが挿入されます。

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Include(b => b.Posts).First();
    var post = new Post { Title = "Intro to EF Core" };

    blog.Posts.Add(post);
    context.SaveChanges();
}

リレーションシップの変更

エンティティのナビゲーション プロパティを変更すると、データベース内の外部キー列に対応する変更が行われます。

次の例では、Blog ナビゲーション プロパティが blog をポイントするように設定されているため、post エンティティが新しい blog エンティティに所属するように更新されます。 コンテキストによって既に追跡されているエンティティ (post) のナビゲーション プロパティによって参照される新しいエンティティであるため、blog もデータベースに挿入されることに注意してください。

using (var context = new BloggingContext())
{
    var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
    var post = context.Posts.First();

    post.Blog = blog;
    context.SaveChanges();
}

リレーションシップの削除

参照ナビゲーションを null に設定するか、コレクション ナビゲーションから関連エンティティを削除することで、リレーションシップを削除できます。

リレーションシップの削除は、リレーションシップに構成された連鎖削除動作に従って、依存エンティティに影響を与える可能性があります。

必須リレーションシップでは、連鎖削除動作が既定で構成され、子/依存エンティティがデータベースから削除されます。 省略可能なリレーションシップでは、連鎖削除は既定では構成されていませんが、外部キー プロパティが null 設定されます。

リレーションシップが必須かどうかを構成する方法については、「Required and Optional Relationships」(必須リレーションシップと省略可能なリレーションシップ) を参照してください。

連鎖削除の動作方法、それらを明示的に構成する方法、および慣例に従った選択方法については、「連鎖削除」を参照してください。

次の例では、BlogPost 間のリレーションシップに連鎖削除が構成されているため、post エンティティがデータベースから削除されます。

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Include(b => b.Posts).First();
    var post = blog.Posts.First();

    blog.Posts.Remove(post);
    context.SaveChanges();
}