在 Entity Framework 6 中保存分离的实体
Posted
技术标签:
【中文标题】在 Entity Framework 6 中保存分离的实体【英文标题】:Save detached entity in Entity Framework 6 【发布时间】:2013-12-25 10:20:59 【问题描述】:我已经阅读了很多关于在实体框架中保存分离实体的帖子。所有这些似乎都适用于旧版本的实体框架。它们引用了似乎不存在的 ApplyCurrentValues 和 ChangeObjectState 等方法。一时兴起,我决定尝试一种通过智能感知找到的方法,并且我想确保这是正确的方法,因为我看不到幕后发生的事情:
public void SaveOrder(Order order)
using (VirtualWebEntities db = new VirtualWebEntities())
db.Orders.Attach(order);
db.Entry(order).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
这是更新已更改的现有项目的正确方法吗?
【问题讨论】:
【参考方案1】:是的,这是正确的。 This article describes various ways of adding and attaching entities,它提供了这个例子:
var existingBlog = new Blog BlogId = 1, Name = "ADO.NET Blog" ;
using (var context = new BloggingContext())
// The next step implicitly attaches the entity
context.Entry(existingBlog).State = EntityState.Modified;
// Do some more work...
context.SaveChanges();
由于 EF 不知道哪些属性与数据库中的属性不同,它将全部更新:
当您将状态更改为已修改时,实体的所有属性都将被标记为已修改,并且所有属性值将在调用 SaveChanges 时发送到数据库。
为避免这种情况,您可以手动set which properties are modified 而不是设置整个实体状态:
using (var context = new BloggingContext())
var blog = context.Blogs.Find(1);
context.Entry(blog).Property(u => u.Name).IsModified = true;
// Use a string for the property name
context.Entry(blog).Property("Name").IsModified = true;
【讨论】:
谢谢。所以我只是想澄清一下.. 不再有以前版本中的 applycurrentvalues 概念,您可以通知 EF 哪些字段发生了变化? @KingOfHypocrites 你可以,我已经编辑了我的答案。我建议你看一下EF6 documentation,它有很多很好的例子和解释,而且写的很直接。 感谢您的链接。您的示例唯一的问题是我必须手动标记每个属性。旧版本有一个 apply values 方法,您可以将新对象应用到旧对象。这将自动标记任何更改的属性,以便在保存时知道要更新的内容。我仍在寻找等价物。 @KingOfHypocrites 我链接的第二篇文章(“使用属性值”)展示了使用其他对象和字典设置属性的几种方法,包括entity.CurrentValues.Set(order)
。我想这就是你要找的。如果您从附加实体开始,它以EntityState.Unmodified
开头。然后使用您选择的任何方法设置属性。该实体将被标记为已修改,并且只会更新那些已更改的属性。
@NiklausWirth 如果您修改 OrderLine 实体,您应该将 OrderLine 实体标记为已修改,而不是在父实体上标记导航属性。以上是关于在 Entity Framework 6 中保存分离的实体的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 6.2.0 - 自动保存哪个用户创建或更新了 DbSet 值的 DbContext
Entity Framework 6 Recipes 2nd Edition(11-9)译 -> 在LINQ中使用规范函数
在 Entity Framework Core 中保存多对多关系