In Entity Framework, how do you update connected entities?

asp.net-mvc-3 c# ef-code-first entity-framework

Question

I have an MVC project and using Entity Framework Code First and POCO objects for the database. 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. 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. When the ActionResult is called to create a new object it works as expected. 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);
}
1
12
12/8/2011 1:20:11 PM

Accepted Answer

I solved it by changing ClassA with a foreign key to ClassB, and setting the value of 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?

4
12/9/2011 9:24:25 AM

Popular Answer

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. Then you'll want to apply any changes to that entity before calling 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.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow