保存相关数据Saving Related Data

除了独立实体以外,还可以使用模型中定义的关系。

提示

可在 GitHub 上查看此文章的示例

添加新实体的关系图Adding a graph of new entities

如果创建多个新的相关实体,则将其中一个添加到上下文时也会添加其他实体。

在下面的示例中,博客和三篇相关文章将全部被插入数据库中。 由于可通过 Blog.Posts 导航属性访问这些文章,因此可发现并添加它们。

  1. using (var context = new BloggingContext())
  2. {
  3. var blog = new Blog
  4. {
  5. Url = "http://blogs.msdn.com/dotnet",
  6. Posts = new List<Post>
  7. {
  8. new Post { Title = "Intro to C#" },
  9. new Post { Title = "Intro to VB.NET" },
  10. new Post { Title = "Intro to F#" }
  11. }
  12. };
  13. context.Blogs.Add(blog);
  14. context.SaveChanges();
  15. }

提示

使用 EntityEntry.State 属性仅设置单个实体的状态。 例如,context.Entry(blog).State = EntityState.Modified

添加相关实体Adding a related entity

如果从已由上下文跟踪的实体的导航属性中引用新实体,则将发现该实体并将其插入到数据库中。

在下面的示例中,插入 post 实体,因为该实体会添加到已从数据库中提取的 blog 实体的 Posts 属性。

  1. using (var context = new BloggingContext())
  2. {
  3. var blog = context.Blogs.Include(b => b.Posts).First();
  4. var post = new Post { Title = "Intro to EF Core" };
  5. blog.Posts.Add(post);
  6. context.SaveChanges();
  7. }

更改关系Changing relationships

如果更改实体的导航属性,则将对数据库中的外键列进行相应的更改。

在下面的示例中,post 实体更新为属于新的 blog 实体,因为其 Blog 导航属性设置为指向 blog。 请注意,blog 也会插入到数据库中,因为它是已由上下文跟踪的实体 (post) 的导航属性引用的新实体。

  1. using (var context = new BloggingContext())
  2. {
  3. var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
  4. var post = context.Posts.First();
  5. post.Blog = blog;
  6. context.SaveChanges();
  7. }

删除关系Removing relationships

可以通过将引用导航设置为 null 或从集合导航中删除相关实体来删除关系。

根据关系中配置的级联删除行为,删除关系可能会对依赖实体产生副作用。

默认情况下,对于必选关系,将配置级联删除行为,并将从数据库中删除子实体/依赖实体。 对于可选关系,默认情况下不会配置级联删除,但会将外键属性设置为 null。

要了解有关如何配置关系必要性的信息,请参阅必选关系和可选关系

有关级联删除行为的工作原理、如何显式配置这些行为以及如何按照约定选择这些行为的详细信息,请参阅级联删除

在下面的示例中,对 BlogPost 之间的关系配置了级联删除,因此将从数据库中删除 post 实体。

  1. using (var context = new BloggingContext())
  2. {
  3. var blog = context.Blogs.Include(b => b.Posts).First();
  4. var post = blog.Posts.First();
  5. blog.Posts.Remove(post);
  6. context.SaveChanges();
  7. }