views:

609

answers:

1

If I have 2 tables in my database: Foo and bar. Foo is identified by FooId and Bar is identifier by BarId. A Bar can have 0 to many Foos therefore Foo has BarId as a foreign key.

I have a model which represents this and an view which can be used to edit a Foo and select (from a dropdown) the associated Bar.

Given the following method on the controller:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formCollection)
{
    Foo originalFoo = FooById(id);

    if (!ModelState.IsValid)
    {
     return View(new VenueViewModel(originalVenue, _db.GetCounties(), _db.VenueTypeSet));
    }

    UpdateModel(originalFoo);

    /* Instead of using UpdateModel I could just iterate through 
       formCollection and manually update originalFoo, it would 
       work but surely there is a better way? */

    _db.SaveChanges();

    return RedirectToAction("Index");
}

The call to UpdateModel throws an InvalidOperationException with no InnerException:

The model of type 'TestApplication.Models.Foo' was not successfully updated.

What's the correct way for my controller to update my Entity Framework-based Model from the drop down in my view?

+6  A: 

No, the default model binder isn't going to be able to do this. You would be hard-pressed to write a custom model binder to do it, also. The HTML SELECT element will only store an ID value in the description, not enough to materialize most entity instances. So we just have to do with the fact that we will be getting an ID only, which is not enough to materialize an entity without hitting the database.

Therefore, when updating an entity's navigation properties, we have two choices:

  1. Read in the entity from the database and assign it to the navigation property in the controller.
  2. Don't attempt to materialize an entity for the navigation property; instead just assign the EntityKey.

The latter is what I do. You can do it in a custom model binder or in a controller. You can read much, much more about doing this at the link, and I have some sample code in the comments at that link.

The new version of the Entity Framework in the forthcoming .NET 4.0 will have a new feature called "FK Associations" which will make this considerably easier.

Craig Stuntz