更新数据
数据库中有主键所对应的记录,修改实体到
更新已跟踪实体的数据
当实体由 DbContext 获取,且默认为已为跟踪状态,当我们改变实体的属性值时,跟踪器将自动将实体的状态修改为
var blog = context.Blogs.First();
blog.Url = "www.xcode.me";
context.SaveChanges();
更新未跟踪实体的数据
对于未被跟踪的断开实体,可通过以下三种方案更新数据。
方案一:显式设置
context.Entry(blog).State = EntityState.Modified;
context.SaveChanges();
方案二:在DbContext 或DbSet 上使用Update 方法
context.Update(blog);
context.SaveChanges();
Update方法 与 设置EntityState方案一样,会将实体状态设置为Modified状态。由于跟踪器没有任何方法来识别哪些属性值已经更改,所以生成的UPDATE语句会更新所有字段属性。
Update方法与显示设置设置EntityState不同的是,Update方法会修改相关实体(如Blog的Posts导航属性)的状态为已修改,从而会为每个实体生成UPDATE语句。如果相关实体没有对应的键值,就会标记为Added 状态,生成一条Insert语句。
方案三:在DbContext 或DbSet 上使用Attach 方法,然后遍历对象图,设置各个属性的状态。
当在已设置键值的实体上使用Attach 方法时,它的状态将被设置为Unchanged 未修改状态,这将导致根本不会生成任何
当在没有键值的实体上使用
context.Entry(entity).IsKeySet
不管怎么说,调用
UPDATE 语句,而不是更新所有字段,这也许会获得更好的性能。
var blog = new Blog
{
BlodId=1,
Name="ZEROBLOG",
Url = "www.xcode.me",
Posts = new List<Post>
{
new Post { Title = "Intro to C#" },
new Post { Title = "Intro to VB.NET" },
new Post { Title = "Intro to F#" }
}
}
_context.Attach(blog);
_context.Entry(blog).Property("Name").IsModified = true;
_context.SaveChanges();
以上代码,生成的
如果实体不使用自动生成的键,则应用程序必须确定是应插入实体还是应更新实体:
public static void InsertOrUpdate(BloggingContext context, Blog blog)
{
var existingBlog = context.Blogs.Find(blog.BlogId);
if (existingBlog == null)
{
context.Add(blog);
}
else
{
context.Entry(existingBlog).CurrentValues.SetValues(blog);
}
context.SaveChanges();
}
TrackGraph 跟踪对象图
在内部,Add、Attach 和 Update 使用图形遍历,为每个实体就是否应将其标记为 Added(若要插
入)、Modified(若要更新)、Unchanged(不执行任何操作)或 Deleted(若要删除)作出决定。 此机制是通过
TrackGraph API 提供了对对象图中各个实体的访问,并允许您对每个实体分别执行定制代码。这在处理这种由不同对象的相关实体的复杂对象图的场景中非常有用。下面的示例复制了一个场景,其中对象图是在Context之外构造的。
var blog = new Blog
{
BlogId = 1,
Name = "zerodo",
Url = "www.xcode.me",
Posts = new List<Post>
{
new Post { PostId=1, Title = "Intro to C#",Content="AAA" },
new Post { PostId=2, Title = "Intro to VB.NET",Content="BBB" },
new Post { PostId=3, Title = "Intro to F#" ,Content="CCC"}
}
};
context.ChangeTracker.TrackGraph(blog, e =>
{
if (e.Entry.Entity is Blog)
{
e.Entry.State = EntityState.Unchanged;
}
if (e.Entry.Entity is Post)
{
e.Entry.State = EntityState.Unchanged;
context.Entry(e.Entry.Entity as Post)
.Property("Title").IsModified = true;
}
});
context.SaveChanges();
以上示例,无论如何修改
更改关系
var blog = new Blog { Name = "zeroblog", Url = "www.xcode.me" };
var post = context.Posts.First();
post.Blog = blog;
context.SaveChanges();
更改关系:可设置导航属性(不存在则创建),也可设置外键的值。