ASP.NET MVC / EF4 / POCO / Repository – How to Update Relationships?

I’ve accepted @jfar’s answer because he put me on the right track, but thought i’d add an answer here for other people’s benefit.

The reason the relationships were not getting updated is for the following reasons:

1) Completely disconnected scenario. ASP.NET = stateless, new context newed up each HTTP request.

2) Edited entity created by MVC (model binding), but not existing in graph.

3) When using POCO’s with no change tracking, performing .Attach on an entity will add it to the graph, but the entity and any child relationships will be Unchanged.

4) I use the stub entity trick and ApplyCurrentValues to update the entity, but this only works for scalar properties, not navigational ones.

So – in order to get the above to work, i would have to explicity set the EntityState for the object (which happens automatically because of ApplyCurrentValues), and also the navigational properties.

And there is the problem – how do i know if the navigational property was added/modified/deleted? I have no object to compare to – only a entity which i know was “edited”, but i don’t know what was edited.

So the solution in the end was this:

[HttpPost]
public ActionResult Edit(Review review)
{
   var existingReview = _service.FindById(review.Id); // review is now in graph.
   TryUpdateModel(existingReview); // MVC equivalent of "ApplyCurrentValues" - but works for ALL properties - including navigationals
   _unitOfWork.Commit(); // save changed
}

That’s it. I don’t even need my _service.Update method – as i don’t need the stub trick anymore – because the review is in the graph with the retrieval, and ApplyCurrentValues is replaced by TryUpdateModel.

Now of course – this is not a concurrency-proof solution.

If i load the Review Edit View, and before i click “Submit” someone else changes the Review, my changes could be lost.

Fortunately i have a “last-in-wins” concurrency mode, so it’s not an issue for me.

I love POCO’s, but man are they a pain when you have the combination of a stateless environment (MVC) and no change tracking.

Leave a Comment