如何更新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