简体   繁体   English

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

[英]How to update related entities in Entity Framework

I have an MVC project and using Entity Framework Code First and POCO objects for the database. 我有一个MVC项目,并为数据库使用Entity Framework Code First和POCO对象。 For example: 例如:

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;}
}

I have an ActionResult that create or edit a model. 我有一个ActionResult,可以创建或编辑模型。 The problem is when I call this ActionResult to update the model, and model.B has been changed, the relation is not saved in the database. 问题是,当我调用此ActionResult来更新模型,并且model.B已更改时,关系不会保存在数据库中。 When the ActionResult is called to create a new object it works as expected. 当调用ActionResult来创建一个新对象时,它按预期工作。 How do I solve this? 我该如何解决这个问题?

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);
}

I solved it by changing ClassA with a foreign key to ClassB , and setting the value of BId : 我通过使用外键将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;}
}

Why does this foreign key property does the job instead of the generated foreign ky of EF? 为什么这个外键属性能够完成工作而不是EF生成的外部ky?

You can't simply call: 你不能简单地打电话:

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

The entity has to be retrieved from the context first so that EF can begin tracking it. 必须首先从上下文中检索实体,以便EF可以开始跟踪它。 Then you'll want to apply any changes to that entity before calling context.SaveChanges() . 然后,您需要在调用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();

This way EF is tracking entity and knows to apply an update against it. 这样,EF就是跟踪entity并且知道对它应用更新。

If you attach and then set the state to modified entity framework will send all properties for update. 如果您附加然后将状态设置为已修改的实体框架将发送所有属性以进行更新。 You don't have to take the otter approach here below as that causes a whole separate load to occur. 您不必采用下面的水獭方法,因为这会导致整个单独的负载发生。 If you do it that way theres no sense in passing in a model, only an id and then you call TryUpdateModel to fill in the properties from the form. 如果你这样做,那么在传递一个模型,只有一个id然后你调用TryUpdateModel来填充表单中的属性是没有意义的。

Personally the attach as modified here is a bit cleaner as it doesn't require a complete round trip because of loading data 个人这里修改的附件有点清洁,因为它不需要完整的往返,因为加载数据

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM