On All Things Web

Apr 24

I was working on a sample MVC 2 project, and wanted to post about the approach I took for updates.  I’m not saying that this is “definitely the way you have to do” any updates to your database.  I was evaluating the approach people were taking when it comes to attaching objects to the context.  MVC’s model binding allows for a posted action method to receive a LINQ to Entity object.  MVC takes the form values posted to the server and, using reflection, supplies the values to the properties of the object, if it can effectively match it.  This is one of the challenges, ensuring that the form values match so the binding works correctly, not so much for one object, but more for complex views binding hierarchies of objects.  But I digress.


 When MVC binds to my model, the object is unattached; this is because it knows nothing about my object related to the context.  With Entity Framework 4, I decided use the AttachTo method as the following:


[HttpPost]
public ActionResult ModifyStory(ProjectStory story)
{
 if (!ModelState.IsValid)
  return View();


 var context = new ProjectTrackingObjectContext();


 if (story.ProjectStoryKey > 0)
  context.AttachTo(context.ProjectStories.EntitySet.Name, story);
 else
 {
  story.CreatedDate = DateTime.Now;
  context.ProjectStories.AddObject(story);
 }


 context.SaveChanges();


 return RedirectToAction(“ModifyStory”, new { id = story.ProjectKey, story = story.ProjectStoryKey });
}


It is pretty convenient; the generated entity sets have a name property that can be used  with AttachTo (you have to supply the name of the entity set; this equaled the type name in EF 1, but with the pluralization of entity names feature in 4, you can’t bank on that).  So attaching the object with the supplied key (if there is a valid key, otherwise an insert happens) works pretty well.

2 comments so far

  1. Jarek Kowalski
    4:29 pm - 4-26-2010

    I am pretty sure that AttachTo() is not enough. By doing so your entity will end up in Unchanged state in which case SaveChanges() will be a no-op.

    What you need to do is:

    context.AttachTo(context.ProjectStories.EntitySet.Name, story);
    context.ObjectStateManager.ChangeObjectState(story, EntityState.Modified);
    context.SaveChanges();

    Then your object should be saved properly.

  2. bmains
    12:39 pm - 8-13-2010

    Hello,

    Yes your right, I posted that prematurely, I should have tested more. Actually, I found out querying the entity first, and then attaching the changes, worked out. Because, if the entity isn’t in the object state entry to begin with, an error can occur.

    Thanks for pointing that out.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>