Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework does not track collection changes when reconnecting an entity

I have been using a lot Entity Framework in a MVVM WPF application recently and I ran into some issues. To display data, my view-models are using a short-live ObjectContext. These view-models will be used in a long running process, therefore I prefered using short-live ObjectContext to not deteriorate performance.

So basically it means that my entities are consumed in disconnected mode. These entites can be created, viewed, updated and deleted. I had no problem for saving changes back to database using disconnected mode. But I found a particular case where changes are not saved with no error showing up on call of SaveChanges() method. This happens when I try to update an entity that has a collection property. Scalar property of the entity are persisted without problem but changes on collections are not reflected to database, like if if it was not able to track these changes on reconnection.

Here is a sample code of my case where I change the entity name and then add an object to its report collection. After SaveChanges(), only the client name has been reflected on database.

this.Client.Name = "Test Client";
this.Client.Reports.Add(new Report { Name = "Test Report" });

using (ReportCompositionEntities entities = new ReportCompositionEntities(this.connectionStringName))
{
    entities.Clients.ApplyCurrentValues(this.Client);
    entities.SaveChanges();
}

So am I doing doing something wrong or EF is simply not able to track this kind of changes when reattaching an entity?

like image 341
Ucodia Avatar asked Jan 31 '12 08:01

Ucodia


1 Answers

That is exactly what happens. There is no change tracking and EF doesn't know about changes performed in navigation property. Also ApplyCurrentValues is able to process only scalar and complex properties. Not navigation properties.

When modifying relations in detached scenarios you must manually tell EF what relations where modified once you attach the entity. You can create some custom logic providing these information and use ObjectStateManager to configure states of all relations or you can simply load the current version with relations from database and manually synchronize changes from detached version to loaded attached version.

Btw. I never used MVVM so I'm not sure how it applies in this case but in case of MVP you can use long living context if it is used for single operation - for example edit view will be handled by its own presenter with its own context. This context will live as long as view will be used to edit single entity / aggregate = it will be used to load entity and the same context will be used to save entity because in this case the edit is performed by same execution context and belongs to single unit of work.

like image 128
Ladislav Mrnka Avatar answered Sep 20 '22 10:09

Ladislav Mrnka