如何更新Entity Framework中的相关实体

我有一个MVC项目,并为数据库使用Entity Framework Code First和POCO对象。 例如:

public class ClassA { public int? Id {get; set;} public string Name { get; set;} public virtual ClassB B {get; set;} } public class ClassB { public int? Id {get;set;} public string Description {get;set;} } 

我有一个ActionResult,可以创建或编辑模型。 问题是当我调用此ActionResult来更新模型,并且model.B已更改时,关系不会保存在数据库中。 当调用ActionResult来创建一个新对象时,它按预期工作。 我该如何解决这个问题?

 public ActionResult Save(ClassA model) { model.B = GetBFromDb(model.B.Id.Value); if(ModelState.IsValid) { if (id.HasValue) { context.Entry(model).State = System.Data.EntityState.Modified; } else { context.ClassAs.Add(model); } context.SaveChanges(); // redirect to index etc. } return View("EditForm", model); } 

我通过使用外键将ClassA更改为ClassB并设置BId的值来解决它:

 public class ClassA { public int? Id {get; set;} public string Name { get; set;} public int BId {get;set;} // foreign key to B public virtual ClassB B {get; set;} } 

为什么这个外键属性能够完成工作而不是EF生成的外部ky?

你不能简单地打电话:

 context.Entry(model).State = System.Data.EntityState.Modified; 

必须首先从上下文中检索实体,以便EF可以开始跟踪它。 然后,您将要在调用context.SaveChanges()之前对该实体应用任何更改。

 var entity = context.ClassAs.Find(model.Id); // set properties you want to modify on entity entity.Name = model.Name; entity.ClassB = context.ClassBs.Find(model.ClassB.Id); // other changes to entity as required... context.SaveChanges(); 

这样,EF就是跟踪entity并且知道对它应用更新。

如果您附加然后将状态设置为已修改的entity framework将发送所有属性以进行更新。 您不必采用下面的水獭方法,因为这会导致完全独立的负载。 如果你这样做,那么在传递一个模型,只有一个id然后你调用TryUpdateModel来填充表单中的属性是没有意义的。

就个人而言,这里修改的附件更加清洁,因为加载数据不需要完整的往返

http://geekswithblogs.net/michelotti/archive/2009/11/27/attaching-modified-entities-in-ef-4.aspx