0

I've been wracking my brain over this for a few days and have tried many "fixes", but all to no avail.

I'm using MVC4 with EF Code first, and the repository pattern on a many-to-many relationship. The tables are created correctly as far as I can tell as when I seed the database, my displaying shows the values correctly.

Where I have issue is when trying to save an Edit. I have an Edit View, with a Listbox containing an enumerated set of objects (B's) and on the Submit (HttpPost), I want to essentially call A.ClassBs.Clear() and db.SaveChanges(). However when I do this, ClassA.ClassBs is not blank.

If, for example, I update another property from A, I have to include db.Entry(ClassA).State = EntityState.Modified before db.SaveChanges() or else the change is not saved to the database.

When I include the EntityState.Modified line, ClassA updates as expected, with the exception of the many-to-many relationship. The ClassA.ClassBs are unchanged.

Here's some

Models
class A
{
  ...
  virtual IEnumerable<ClassB> ClassBs {get;set;}
}

class B
{
  ...
  virtual IEnumerable<ClassA> ClassAs {get;set;}
}

Controller
public ActionResult Edit(int id - 0)
{
   ... (create viewmodel)
   return View(viewmodel)
}

[HttpPost]
public ActionResult Edit(viewmodel)
{
  viewmodel.A.ClassBs.Clear();
  db.Entry(viewmodel.A).State = EntityState.Modified;
  db.SaveChanges();
}

View
@Html.ListBoxFor(model => model.ClassA.ClassBs, Model.ClassBs)

Something odd is going on with my binding. What am I doing wrong?

  • 2
    when the Edit action is called on post, the viewmodel you got as parameter is "detached", so you have to attach it to apply any changes on it. – dvjanm Oct 17 '13 at 08:17
  • Could you elaborate a bit? I'm not familiar with attaching and detaching entities. – CrazyTegger Oct 17 '13 at 15:11
  • According to this post: http://stackoverflow.com/questions/7512636/dbcontext-state-and-original-values, setting the ClassA's entry's state to Modified takes care of the attaching for me. However that still does not update ClassA.ClassBs as I expect. – CrazyTegger Oct 17 '13 at 15:31
  • I think this is because of this line: viewmodel.A.ClassBs.Clear(); You remove the references. So why would it be updated? – dvjanm Oct 17 '13 at 17:07
  • Thanks for the reply jannagy. For proof of concept, I'm purposefully trying to remove the references. Shouldn't EF know that I've removed them, and thus update the lookup table for ClassAClassBs? Also, one thing I'm noticing here is that in the HTTP post, the ClassA.ClassBs is an empty list - is that meaning the model binding didn't work? – CrazyTegger Oct 17 '13 at 17:17
  • I've got numerous other one-to-many relationships in ClassA, and I've noticed that they all required an associated Id in order for them to work correctly with EF. By this same token, does that mean I need an IEnumerable ClassBIDs in ClassA? – CrazyTegger Oct 17 '13 at 17:21
  • How have you displayed it in the view? If not try to add it to the view with Html.DisplayFor or Html.HiddenFor. This way it must be posted back. – dvjanm Oct 17 '13 at 17:22
  • Added the view to the original question – CrazyTegger Oct 17 '13 at 17:27

1 Answers1

0

You call viewmodel.A.ClassBs.Clear() on a detached entity. You need to attach the entity and it's related ClassB's before you call Remove or Clear so that the context knows what to delete.

how-to-delete-many-to-many-relationship-in-entity-framework

How to Add/Attach and Entity States

Community
  • 1
  • 1
Colin
  • 22,328
  • 17
  • 103
  • 197
  • Thanks. I started going through this, but apparently I don't have the Attach method available. my context is defined as: public class EFDbContext : DbContext { public DbSet ClassBs{ get; set; } } Do I manually have to create this method? – CrazyTegger Oct 17 '13 at 18:45
  • I must be missing something here, I have no attach methods on the Entity class, however I do on the context. The solution described in your link has Entities who have the attach method. Also, the given solution deletes the ClassB entirely. All I want to do is remove the links, not delete the entire class. – CrazyTegger Oct 17 '13 at 19:27