Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to transfer an Entity Framework object over the web and back via JSON

I've got some MVC code that serializes an EF 3.5 object into an anonymous type for return as a JSON result to an AJAX call on my page. The hurdle I have is that when I send the object back to the server via JSON, (and let the ModelBinder deserialize it for me into my EF type), I have to update it in my Entity Framework context manually. Or at least that's what I'm doing now. It has no EntityKey, so attaching it fails. I end up having to look up the old object and update it property by property. Any ideas around this? Is the solution to pass the EntityKey around with my object?

Here's what I have:

    public void Update(Album album)
    {
        using (var db = new BandSitesMasterEntities())
        {
            var albumToUpdate = db.Album.First(x => x.ID == album.ID);

            albumToUpdate.AlbumTitle = album.AlbumTitle;
            albumToUpdate.Description = album.Description;
            albumToUpdate.ReleaseYear = album.ReleaseYear;
            albumToUpdate.ImageURL = album.ImageURL;
            albumToUpdate.OtherURL = album.OtherURL;

            db.SaveChanges();
        }
    }

And here's what I'd like to do, or something similar:

    public void Update(Album album)
    {
        using (var db = new BandSitesMasterEntities())
        {
            db.Attach(album)
            db.SaveChanges();
        }
    }
like image 646
AVH Avatar asked Jan 29 '10 21:01

AVH


3 Answers

or you could use AutoMapper to map those fields for you, so you'd just add one extra line to your example.

like image 106
Robert Ivanc Avatar answered Oct 10 '22 21:10

Robert Ivanc


Why not just use the UpdateModel or TryUpdateModel controller methods instead? It works really well with EF and you can even explicitly set the included property list.

The id parameter will auto-map via the MVC framework to the hidden field on your form specifying the id.

public void Update(int id, FormCollection collection)
{
    using (var db = new BandSitesMasterEntities())
    {
        var albumToUpdate = db.Album.First(x => x.ID == id);

        //use UpdateModel to update object, or even TryUpdateModel
        UpdateModel(albumToUpdate, new string[] { "AlbumTitle", "Description", "ReleaseYear", "ImageURL", "OtherURL" });

        db.SaveChanges();
    }
}
like image 29
RollemIra Avatar answered Oct 10 '22 19:10

RollemIra


This became much easier for us in EF 4.0. This is what we did in EF 3.5:

public static void AttachAsModified(this ObjectContext objectContext, string setName, object entity,
                                    IEnumerable<String> modifiedFields)
{
    objectContext.AttachTo(setName, entity);
    ObjectStateEntry stateEntry = objectContext.ObjectStateManager.GetObjectStateEntry(entity);
    foreach (String field in modifiedFields)
    {
        stateEntry.SetModifiedProperty(field);
    }
}

And then:

using (var db = new BandSitesMasterEntities())
{
    db.AttachAsModified("Album", album, new string[] { "AlbumTitle", "Description", "ReleaseYear", "ImageURL", "OtherURL" })
    db.SaveChanges();
}

It becomes more complicated if you have foreign key constraints, but it looks like you don't.

like image 23
StriplingWarrior Avatar answered Oct 10 '22 21:10

StriplingWarrior