Tracking changes in complex object graph RRS feed

  • Question

  • Hello,

    I started to think about tracking changes in complex object graph in disconnected application few days ago. I have already found several solutions but I would like to know if there is any best practice or what solution do you use and why? I passed similar question to Entity framework forum but this time I am more interested in architecture globally.

    The problem in my case is defined in multi layered architecture (not necessarily n-tier at the moment) as follows:

    • Layer of repositories to deal with persistence (ORM tool doesn't matter at the moment).
    • Set of POCO classes representing domain entities. Repositories persists those classes and returns them as results of queries.
    • Set of Domain services working with domain entities.
    • Facade layer defining gateway to business logic. Internally it uses repositories, domain services and domain objects. Domain objects are not exposed - each facade method uses set of specialized Data transfer objects for parameter and return value. It is responsibility of each facade method to transform domain entity to DTO and vice-versa.
    • Modern web application which uses facade layer and DTOs - I call this disconnected application. 

    Now suppose that one of the domain object is Order which has Order details (lines) and related Orders. When the client requests Order for editation it can modify Order, add, remove or modify any Order detail and add or remove related Orders. All these modifications are done on data in the web browser - javascript and AJAX. So all changes are submit in single shot when client pushes the save button. The question is how to handle these changes? Generally repository needs to know which entities and relationships were modified, inserted or deleted. I ended with two "best" solutions:

    1. Store initial state of DTO in hidden field (in worse case to session). When receiving request to save changes create new DTO based on received data and second DTO based on persisted Data. Merge those two and track changes. Send merged DTO to business layer and use received information about changes to properly set up entity graph. This requires some manual change tracking in domain object so that change information can be set up from scratch and later on passed to repository - this is the point I am not very happy with.
    2. Do not track changes in DTO at all. When receiving modified data to business layer create modified entity and load actual state from repository (generally additional query to database - this is the point I am not very happy with) - merge these two entities and automatically track changes by entity proxy provided by ORM tool. Special care is needed for concurrency handling because actual state does not have to be the initial state.

    What do you think about that? What do you recommend?

    Best regards,

    Tuesday, August 3, 2010 9:03 PM

All replies

  • I don't have too much experience with EF but my understanding of how it could work aligns with yours.  You either have to create self tracking entities and store them in ViewState/Session, modify them, and ship them back for processing.  The other option is as you described which is simply requery the data so the context has original values to go against.  I think lastly if you were willing to give up concurrency handling perhaps you can force an update for example with a last-in-wins scenario.

    I believe I've used the last-in-wins approach last with EF1 a few years back, basically attaching the new entity to the context and setting all properties to modified.  Now with EF4 and self tracking entities I believe I would attempt to go down the storing the entities in Session/ViewState, if the number of object permits.  I think one of the other issues with that approach is that the entities are not serializable out of the box, but I believe there are templates out there to help with that.

    Wednesday, August 4, 2010 12:35 PM