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:
- 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.
- 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,
Ladislav