简体   繁体   中英

Entity Framework - Saving changes made to a detached entity

Say changes have been made to a detached entity in EF 4. If we want to save theses changes when we re-attached the entity, is it possible to do this with ApplyCurrentValues without querying the DB to get the original entity? I don't think so, but I'd like somebody to confirm that.

using (var ctx = new BAEntities())   
{
var firstCust = (from c in ctx.Contacts select c).First();
Console.WriteLine(firstCust.FirstName);
ctx.Contacts.Detach(firstCust);

firstCust.FirstName = "Modified Value";
ctx.Contacts.Attach(firstCust);
ctx.ApplyCurrentValues("Contacts", firstCust);//Does not work

//ctx.ObjectStateManager.ChangeObjectState(firstCust, EntityState.Modified); //Works with that line
            ctx.SaveChanges( );
}

Thank you

I can confirm your guess. It doesn't work this way.

When you call Attach with an entity as parameter EF adds the entity to the context in state Unchanged . Basically you are telling EF with Attach that all property values the entity has at that time represent the current values in the database.

ApplyCurrentValues is kind of an "automapper" that just copies the property values of the object you pass into ApplyCurrentValues to the attached entity that has the same key. This copy happens based on the property name.

If a property value of the attached entity is different to the property value of the object you pass into ApplyCurrentValues EF marks the property as Modified . If not the state stays Unchanged . Obviously with your procedure all property states will stay unchanged and nothing gets written to the database.

In theory you could do crazy stuff to make it work like:

firstCust.FirstName = "Modified Value";
var dummyCust = new Contact { FirstName = "UnlikelyNameThatWillNeverOccur" };
ctx.Contacts.Attach(dummyCust);
ctx.ApplyCurrentValues("Contacts", firstCust);

Here the FirstName property would be marked as Modified . But you had to do this for every property and the result will be the same as setting the state of the whole entity to Modified as you did in the commented code line.

You can by the way set a single property to Modified :

ctx.Contacts.Attach(firstCust);
ctx.ObjectStateManager.GetObjectStateEntry(firstCust)
    .SetModifiedProperty("FirstName");

This will send an UPDATE statement to the database that only sets the FirstName column value (while setting the state of the whole entity to Modified will create an UPDATE statement that sets all column values to the current property values).

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