Mirko Lugano
Mirko Lugano

Reputation: 985

Breeze Merge strategy: overwrite properties, keep changes

I have a web app where I use breeze. I do partial loading of entities, that means in one load I fill certain properties of the entity, on another load I fill other properties. Example: this would be my entitiy definition (pseudo-code, javascript):

myEntity = {
  property1: '',
  property2: '',

  property3: '',
  property4: '',
}

Let's assume I do a first load and I fill property1 and property2. Then I change manually the value of property1 so that my entity is included in the pending changes. I don't save the changes yet. Now I do the second load (with the MergeStrategy set to OverwriteChanges otherwise, since my entity has a pending change, its properties won't be updated). At the end of this second load operation, property3 and 4 get filled, and I still have my manually modified value of property1 on the entity, but the point is that the pending changes are lost (correctly, according to Breeze documentation) but I still would like to have property1 set as pending change (to be able to save it) since I have not yet saved it. Is that achievable somehow?

Upvotes: 2

Views: 938

Answers (2)

Mirko Lugano
Mirko Lugano

Reputation: 985

I had quickly tried the approach by Jay and, apart from the complexity of creating another entityManager (with the same metadataStore otherwise I cannot attach entities from one manager to the other), provided also that I have a 'metadataByHand' store with a custom DataService (custom adapter), and it's quite complex to put it all together, I saw that when merging the properties from the second load to the already 'Modified' entity I cannot retrieve which properties have been loaded in that subset (we have multiple subsets) and therefore I think this approach is not right for me. Thus I have decided to perform a saveChanges() automatically before every loading, and only when the save has finished, load the second part. In this case there is no chance of 'pending changes' being cancelled.

Upvotes: 0

Jay Traband
Jay Traband

Reputation: 17052

What you want can be accomplished, but you will need to write some code for it. By default, breeze either updates an entire entity (MergeStrategy.OverwriteChanges) or skips the entire entity if it has been in any way previously modified ( MergeStrategy.PreserveChanges).

It sounds as if you want some form of partial update of the entity. In order to accomplish this you will need to perform the merge yourself, however breeze does provide you with enough 'rope' to perform this task.

  • Execute your query into a new empty 'temporary' EntityManager.
  • For each of the entities returned by the query in the 'temporary' EntityManager.
    • Find the corresponding entity in the 'real' EntityManager. (You can use the EntityManager.getEntityByKey method for this.)
    • If the entity is found, use the originalValues map (EntityAspect.originalValues) in the 'found' entity to determine whether there is an original value for each property and update ( or not) the found entity based on this information.
    • If the entity is not found, detach it from the 'temporary' EntityManager (EntityManager.detachEntity) and attach it to the 'real' EntityManager (EntityManager.attachEntity).

Hope this helps.

Upvotes: 2

Related Questions