Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracking changes in Entity Framework 4.0 using POCO Dynamic Proxies across multiple data contexts

I started messing with EF 4.0 because I am curious about the POCO possibilities... I wanted to simulate disconnected web environment and wrote the following code to simulate this:

  1. Save a test object in the database.
  2. Retrieve the test object
  3. Dispose of the DataContext associated with the test object I used to retrieve it
  4. Update the test object
  5. Create a new data context and persist the changes on the test object that are automatically tracked within the DynamicProxy generated against my POCO object.

The problem is that when I call dataContext.SaveChanges in the Test method above, the updates are not applied. The testStore entity shows a status of "Modified" when I check its EntityStateTracker, but it is no longer modified when I view it within the new dataContext's Stores property. I would have thought that calling the Attach method on the new dataContext would also bring the object's "Modified" state over, but that appears to not be the case. Is there something I am missing? I am definitely working with self-tracking POCOs using DynamicProxies.

private static void SaveTestStore(string storeName = "TestStore")
{
  using (var context = new DataContext())
  {
    Store newStore = context.Stores.CreateObject();
    newStore.Name = storeName;
    context.Stores.AddObject(newStore);
    context.SaveChanges();
  }
}

private static Store GetStore(string storeName = "TestStore")
{
  using (var context = new DataContext())
  {
    return (from store in context.Stores
            where store.Name == storeName
            select store).SingleOrDefault();
  }
}

[Test]
public void Test_Store_Update_Using_Different_DataContext()
{
  SaveTestStore();
  Store testStore = GetStore();
  testStore.Name = "Updated";      

  using (var dataContext = new DataContext())
  {
    dataContext.Stores.Attach(testStore);
    dataContext.SaveChanges(SaveOptions.DetectChangesBeforeSave);        
  }

  Store updatedStore = GetStore("Updated");
  Assert.IsNotNull(updatedStore);
}
like image 657
Rob Packwood Avatar asked Apr 15 '10 01:04

Rob Packwood


2 Answers

After playing around with the self-tracking entities, I realised what was your mistake. Instead of trying to attach the entity to the data context, you should instead instruct that you want the data context to apply the new changes you have made to it to the database.

In this case, change the "saving" code to this:

using (var dataContext = new DataContext())
{
    dataContext.Stores.ApplyChanges(testStore);
    dataContext.SaveChanges();        
}

At least I have tested it on my local machine, and it worked after this update :)
Hope this helps!

like image 184
Artiom Chilaru Avatar answered Nov 09 '22 23:11

Artiom Chilaru


Try

        db.ObjectStateManager.ChangeObjectState(user, System.Data.EntityState.Modified);

Before calling SaveChanges

like image 31
Aidan Avatar answered Nov 09 '22 23:11

Aidan