除了独立实体外,还可以利用模型中定义的关系。
小窍门
可以在 GitHub 上查看本文 的示例 。
添加新实体的图表
如果创建多个新的相关实体,将其中一个添加到上下文中会导致其他实体也被添加。
在以下示例中,博客和三篇相关文章都插入到数据库中。 找到并添加这些帖子,是因为它们可以通过 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);
await context.SaveChangesAsync();
}
小窍门
使用 EntityEntry.State 属性仅设置单个实体的状态。 例如,context.Entry(blog).State = EntityState.Modified
。
添加相关实体
如果从上下文已跟踪的实体的导航属性引用新实体,则会发现该实体并将其插入到数据库中。
在下面的示例中,由于从数据库中提取的 post
实体的 Posts
属性中添加了 blog
,因此插入了该实体。
using (var context = new BloggingContext())
{
var blog = await context.Blogs.Include(b => b.Posts).FirstAsync();
var post = new Post { Title = "Intro to EF Core" };
blog.Posts.Add(post);
await context.SaveChangesAsync();
}
关系变化
如果更改实体的导航属性,则会对数据库中的外键列进行相应的更改。
在以下示例中,实体 post
将更新为属于新 blog
实体,因为它的 Blog
导航属性设置为指向 blog
。 请注意,blog
也会插入到数据库中,因为它是一个新实体,并且被一个已经由上下文post
跟踪的实体的导航属性所引用。
using (var context = new BloggingContext())
{
var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
var post = await context.Posts.FirstAsync();
post.Blog = blog;
await context.SaveChangesAsync();
}
删除关系
可以通过将引用导航 null
设置为或从集合导航中删除相关实体来删除关系。
根据关系中配置的级联删除行为,删除关系可能会对依赖实体产生副作用。
默认情况下,对于必需的关系,将配置级联删除行为,并从数据库中删除子/从属实体。 对于可选关系,默认情况下不会配置级联删除,但外键属性将设置为 null。
请参阅 “必需”和“可选关系 ”,了解如何配置关系的必需性。
请参阅 Cascade Delete ,详细了解级联删除行为的工作原理、如何显式配置它们以及如何按约定选择它们。
在以下示例中,级联删除配置在Blog
与Post
之间的关系上,因此post
实体将从数据库中删除。
using (var context = new BloggingContext())
{
var blog = await context.Blogs.Include(b => b.Posts).FirstAsync();
var post = blog.Posts.First();
blog.Posts.Remove(post);
await context.SaveChangesAsync();
}