4

Is there any method to update an object from a strongly typed object without listing each field ?
Lets consider the following case:

    using (var context = new MyDBEntities())
{
     var user = (User)Session["EditedUser"];
     var oldUser = context.Users.FirstOrDefault(o => o.Id == user.Id);
     oldUser.FirstName= user.FirstName;
     oldUser.LastName = user.LastName;
     etc ....
     context.SaveChanges();
}

I have 29 more fields and I am not willing to write them down one by one every time. What I am looking for should be similar to this

using (var context = new MyDBEntities())
{
     var user = (User)Session["EditedUser"];
     var oldUser = context.Users.FirstOrDefault(o => o.Id == user.Id);
     oldUser=user;
     context.SaveChanges();
}

Which fails for sure because of the entity's primary key violation. What I would like to achieve here is to update all the fields except the primary key value.

3
  • 1
    Have you tried to attach it? e.g. db.Users.Attach(user); db.Entry(user).State = EntityState.Modified; Commented Dec 23, 2013 at 10:28
  • The user is already in the database, I am trying to update his properties from another user object. Attach will not reference to the old user, It will be attached as a new user. Commented Dec 23, 2013 at 10:35
  • 1
    AddObject would be a new user, not Attach if you set the [Key] column to the same value of the existing user. Commented Dec 23, 2013 at 11:14

2 Answers 2

4

Used the Attach function thanks to 'Silvermind' Now my code looks like this

using (var context = new MyDBEntities())
{
    try
    {
        var user = (User)Session["EditedUser"];
        context.Users.Attach(user);
        context.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);
        context.SaveChanges();
        Session["EditedUser"] = null;
        return "ok";
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

4

I know the accepted answer is seven year old as of this post, so it is likely done a different way now. I found an alternative method that works from this source. One additional note that I found was that you have to then save the object. Here is a full code example in what worked for me. This turned out to be truly priceless as I have performed many work around methods in updating old/ new objects and this makes it a real one stop shop!

EDIT: Modified to match the much simpler format suggested by Gert Arnold

    [ResponseType(typeof(Order))]
    public IHttpActionResult PutOrder(Order ord)
    {
        if (!ModelState.IsValid)
        {
            return Content(HttpStatusCode.BadRequest, "Could not save order, invalid model.");
        }
        var current = db.Order.Find(ord.OrderId);
        try
        {              
            if (current != null)
            {
                // Update Order in Six Hat to match order in IB
                db.Entry(current).CurrentValues.SetValues(ord);
                db.SaveChanges();
                // TODO: Send Order Change Notifications
            }
        }
        catch(Exception e)
        {
            return Content(HttpStatusCode.BadRequest, e.Message);
        }

        return Ok(current);
    }

5 Comments

Unfortunately, the redundant line db.Entry(current).State = System.Data.Entity.EntityState.Modified; throws away the advantages of CurrentValues.SetValues, which is a leaner update statement. See stackoverflow.com/a/30824229/861716.
@GertArnold Thank you for that... I just basically followed the model that was in the link. Appreciate the much better and simpler format of your method!
Does this do nested objects, IE navigation properties?
@VictorioBerra That is a good question that I must admit that I have not tried yet. However, it makes sense to me that if you can initially save them that way (make sure you have all the includes())... then you should be able to update them that way.
@anthonygriggs I tested and unfortunately it does not. I'm gonna keep using AutoMapper

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.