简体   繁体   中英

Entity Framework Modify Detached Object

I have some confusion, stemming from this http://msdn.microsoft.com/en-us/library/vstudio/bb896248(v=vs.100).aspx regarding modifying a detached object.

That seems to indicate if I modify an object in a detached state, when I reattach, I should use ApplyOriginalValues instead of ApplyCurrentValues. However, when I do this, it seems to never update the object as in the example, unless I modify the object after reattaching it. However if I modify after attaching, then it doesn't seem to matter which of these I use (applyoriginal or applycurrent).

Here is my code:

//this never works
            private void UpdateWithOriginal(Category cat, string name)
            {
                using (TestContext ctx = new TestContext())
                {
                    cat.Name = name;
                    ctx.Categories.Attach(cat);
                    ctx.ApplyOriginalValues("Categories", cat);
                    var state = ctx.ObjectStateManager.GetObjectStateEntry(cat).State;  //never modified state here
                    ctx.SaveChanges();
                }
            }

            //this always works
            private void UpdateWithCurrent(Category cat, string name)
            {
                using (TestContext ctx = new TestContext())
                {
                    ctx.Categories.Attach(cat);
                    cat.Name = name;
                    ctx.ApplyCurrentValues("Categories", cat);
                    var state = ctx.ObjectStateManager.GetObjectStateEntry(cat).State;
                    ctx.SaveChanges();
                }
            }

Does anyone know why the MSDN link seems to indicate that the //this never works, bit should work?

This ended up being so easy. I don't know why I didn't understand it. Here is the solution to this:

private void UpdateWithOriginal(Category cat, string name)
        {
            Category updatedObject = new Category()
            {
                CategoryID = cat.CategoryID,
                Name = cat.Name,
                Topics = cat.Topics
            };
            updatedObject.Name = name;
            using (TestContext ctx = new TestContext())
            {
                ctx.Categories.Attach(updatedObject);
                ctx.ApplyOriginalValues("Categories", cat);
                var state = ctx.ObjectStateManager.GetObjectStateEntry(updatedObject).State;  //never modified state here
                ctx.SaveChanges();
            }
        }

What I was missing is this. You have two objects, an original and an updated. You detach, send one off to a WCF service, changes are made, object is sent back, on your end you recreate the object as an updated object. Now in order to update your context, you need two objects, because with the given code, if you attach to your context the updatedObject, the status of your entity is this:

  • Original Values- Name = Bob
  • Current VAlues- Name = Bob

There is no different, so .SAveChanges() won't do anything. Since you attatched the updated object, you MUST use ApplyOriginalVAlues("Categories",OriginalCategory) to cause this:

  • Original VAlue: Name = Steve
  • Current Value: Name = Bob

Now you have a modified object and when you call .SaveChanges() the change will take effect. The reverse of this is true if you attach the original object (you will need to not modify the original value, but the current value, so you use ApplyCurrentVAlues()).

I think you're just misreading the MSDN article..

From the MSDN Definition of ApplyOriginalValues :

Copies the scalar values from the supplied object into set of original values for the object in the ObjectContext that has the same key.

From the MSDN Definition of ApplyCurrentValues :

Copies the scalar values from the supplied object into the object in the ObjectContext that has the same key.

Which is exactly the behavior you're seeing. ApplyOriginalValues goes back to the database and updates the values. ApplyCurrentValues uses the values in the object that you have, so you can update the changes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM