My Inbox: How to save changes coming from disconnected POCOs

I receive a lot of random emails from developers with Entity Framework questions. (This is not a request for more! :)) If I’m too busy to even look or if it’s something I can’t answer off the top of my head, I swallow my pride and ask the person to try the MSDN forums. If the email is from a complete stranger and has gobs and gobs of code that email will surely get a "please try MSDN forums" reply. 

But sometimes I’m not in my usual state of “too much to do” panic and get a question that is short & sweet and I can answer it effortlessly. This is one of those types of questions.

Question from Arda Çetinkaya

Hi;

I am contacting with you with a suggestion of my friend who is one of the best MVPs of Turkey…So I have a small question if you can answer it I will be very happy…

What I am trying to do is updating a poco entity with entity framework…My poco entity is not in context,so I am attaching it first…But no change is done…How can I update my poco entities…If you have any resource for it,I really need it…

Reply

You would have the same problem with EntityObjects as with POCOs. If you are using EF4, then you have a lot of options that you did n ot have in EF1.

Assuming it’s EF4, the simplest is to use the new ObjectContext.ObjectStateManager.ChangeState (might be ChangeObjectState) method. But that means you need to know what the state should be …added, updated or deleted.

That’s just one way and might be just what you need or might not fit your scenario.

If you search for changestate/changeobjectstate and Entity Framework on the web you should find lots of blog posts and articles on this.

Good Luck

julie

Follow-up from Arda 20 minutes later

Thanks a lot for your reply…It helped me to clear it out…

With the following code change, I got it…Thanks a lot…You saved my life (:

 public static void UpdateConfigurationSetting(ConfigurationSetting configurationSettingToUpdate)
{
  try
  {
    using (DBEntities entities = new DBEntities ())
    {
      entities.ConfigurationSetting.Attach(configurationSettingToUpdate);
      ObjectStateEntry entry = entities.ObjectStateManager
.GetObjectStateEntry(configurationSettingToUpdate); entry.ObjectStateManager
.ChangeObjectState(configurationSettingToUpdate, System.Data.EntityState.Modified); entities.SaveChanges(); } } }

  Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!  

3 thoughts on “My Inbox: How to save changes coming from disconnected POCOs

  1. Shouldn’t the SaveChanges() method pick up on the state of the POCO entity (assuming it is tracked via a dynamic proxy at runtime)?

    The problem I have been having with the EF 4.0 POCO model is that when I keep a POCO object in memory between requests, the POCO object does in fact correctly track it’s state when using a dynamic proxy ("Modified" when the entity is updated on the last request). However when attaching the entity to a new DataContext in order to persist, it seems kind of silly to me that when the entity is attached, it loses it’s status of "Modified" on the new DataContext. Any clue why that happens? It seems like there should be an option on the Attach method to allow the entity to keep that "Modified" state.

  2. I ran in the same problem as Rob.

    I wrote two extention methods to do updates between contexts

    first detach the item properly from the context. With Detach the change tracker is not reset:

    public static void DetachAndUntrack<T>(this ObjectContext context, T entityItem) where T : EntityObject

    {

    IEntityWithChangeTracker tracker = entityItem;

    //detach the item from the current context

    context.Detach(entityItem);

    //the change tracker in the item needs to be set to null, to allow an other context to do the chage tracking

    //this is NOT done in the Detach method

    tracker.SetChangeTracker(null);

    }

    Saving the changes:

    By looking up the object by the key it spins up change tracking:

    public static void AttachAndSave<T>(this ObjectContext context, IEnumerable<T> entityItems) where T : EntityObject

    {

    foreach (var entityItem in entityItems)

    {

    // getting the orginalItem to spinup EF change tracking

    var orginalItem = context.GetObjectByKey(entityItem.EntityKey);

    //updating the item

    context.ApplyCurrentValues(entityItem.EntityKey.EntitySetName, entityItem);

    //saving the changes if any

    }

    context.SaveChanges();

    }

    I use it in an asp.net MVC 2 and works great, but I have not tried it yet with complex objects

    For questions or suggestions contact me via twitter @sven_schimmel

    Sven

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.