如何更新实体框架中的相关实体

本文关键字:实体 框架 何更新 更新 | 更新日期: 2023-09-27 18:17:05

我有一个MVC项目,并使用实体框架代码优先和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生成的外键?

你不能简单地调用:

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并知道对它应用更新

如果您附加并设置状态修改实体框架将发送所有属性更新。您不必采用下面的水獭方法,因为这会导致整个单独的负载发生。如果你这样做,传递一个模型就没有意义了,只有一个id,然后你调用TryUpdateModel来填充表单的属性。

我个人认为这里修改的附件更干净一些,因为它不需要完整的往返,因为加载数据

http://geekswithblogs.net/michelotti/archive/2009/11/27/attaching -修改-实体- - ef - 4. - aspx