locked
Updating Detached Object - RRS feed

  • Question

  • I've been experimenting with updating detached objects following the examples in the help topic entititled How to: Apply Changes Made to a Detached Object (Entity Framework).  I had success following the second example that uses TryGetObjectByKey to query the "original" entity object from the database, but the technique that shows re-attaching an object and then modifying it via ApplyPropertyChanges is giving me this exception when ApplyPropertyChanges is called:

    System.InvalidOperationException: The property 'SurveyId' is read-only because it is part of the entity's key..

    Funny thing is, I've stepped through the My Travel sample (from EF Samples on Codeplex) that uses a WCF Service that does the same thing in its UpdateComments operation and it works. I'm trying to figure out how my model or code differs and can't figure it out.  Anyone seen this exception or see what I'm doing wrong? Thanks.

    public static void UpdateSurvey(Survey original, Survey modified)
    {
        using (SampleEntities db = new SampleEntities())
        {
            db.Attach(original);
            db.ApplyPropertyChanges("Survey", modified);
            db.SaveChanges();
        }
    }

    [TestMethod()]
    public void UpdateSurveyWithAttachTest()
    {
        Survey original = AppService.GetSurvey(116);
        Survey modified = new Survey();
       
        modified.EntityKey = original.EntityKey;
        modified.Description = DateTime.Now.ToLongTimeString();

        AppService.UpdateSurvey(original, modified);
    }
    Saturday, February 16, 2008 12:17 AM

Answers

  • Change the following line:

    Incorrect

     

    Survey modified = new Survey();

     

    modified.EntityKey = original.EntityKey;

    to

    Correct

     

    Survey modified = new Survey{ SurveyId = 116 };

     

     

    The modified object needs it's own EntityKey instance, with the key value being the same as the original.
    Monday, February 18, 2008 6:14 AM
  • ApplyPropertyChanges does look at all scalar value properties and attempts to set them if they are different. This means the key fields must match unless the original value is in the "Added" state (which is the only time key fields are updateable).

     

    For the WCF case, during serialization an entity's EntityKey is also serialized so upon deserialization you will get a new Entitykey instance as you suspected.

     

    Jeff

     

    Tuesday, February 19, 2008 4:48 PM

All replies

  • Change the following line:

    Incorrect

     

    Survey modified = new Survey();

     

    modified.EntityKey = original.EntityKey;

    to

    Correct

     

    Survey modified = new Survey{ SurveyId = 116 };

     

     

    The modified object needs it's own EntityKey instance, with the key value being the same as the original.
    Monday, February 18, 2008 6:14 AM
  • Thanks.  That works. 

    A couple of notes: 

    I was under the impression (wishful thinking) that the ApplyPropertyChanges was able to change ONLY the properties I had set on the modified object.  This is not the case.   It applies all properties except navigation properties and related object properties. 

    I was following another example from codeplex that has code like this, but it is using a wcf service and stuff is being serialized/deserialized. Perhaps the original and modified end up with their own EntityKey instances because of that.

     

    Comment newComment = new Comment();

    newComment.EntityKey = c.EntityKey;

    newComment.CommentID = c.CommentID;

    newComment.CommentText = c.CommentText + "*";

     

    Tuesday, February 19, 2008 4:25 PM
  • ApplyPropertyChanges does look at all scalar value properties and attempts to set them if they are different. This means the key fields must match unless the original value is in the "Added" state (which is the only time key fields are updateable).

     

    For the WCF case, during serialization an entity's EntityKey is also serialized so upon deserialization you will get a new Entitykey instance as you suspected.

     

    Jeff

     

    Tuesday, February 19, 2008 4:48 PM