开发者

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;
         开发者_如何学Go   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();
        }
    }


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


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();
    }
}


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.


There is no way around the entity key issue. You either have to add it to your anonymous type or I would recommend you port your code to using data services.

http://www.hanselman.com/blog/jQueryToShipWithASPNETMVCAndVisualStudio.aspx

which would allow you to do all of the db manipulation on the client side.

http://msdn.microsoft.com/en-us/data/bb931106.aspx


Did you try something like:

object original;
var key = contexte..CreateEntityKey("EntitySet", modified);
if(contexte.TryGetObjectByKey(key, out original))
{
    var originalEntity = (YourEntityType)original;
    // You have to mannualy set your entityKey
    originalEntity.YourEntityReference.EntityKey = new EntityKey("Entities.EntitySet", "Id", modified.YourEntity.Id);

    contexte.ApplyPropertyChanges("EntitySet", modified);
}
contexte.SaveChanges();

Assuming that your EntityReference are set by dropDown, you'll still have the Id


In your Album entity's partial class you may define a CopyFrom function and call it from your Update function

partial class Album
{
   public void CopyFrom(Album album)
   {
   //individual field copying here
   }
}


 public void Update(Album album) 
    { 
      ...
      albumToUpdate.CopyFrom(album);
      ...
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜