Question

I create a new Entity in EntityManager like this:

var newCust = manager.createEntity('Customer', { Name: 'MyNewCustomer' });

it's Id is correctly generated. On a Button-Click I save the Entity on the Server:

manager.saveChanges([newCust]).then(function (saveResult) {
  alert('saved!');
}

Now everything works perfect BUT, the Entity in newCust keeps it's EntityState "Added". It doesn't change to "Unchanged".

I've debugged a little and found out, that in the function "mergeEntity(mc, node, meta)" of breeze, where the following code happens - no entity is found (eventhough the key it searches is the same Id - the Id-Fixup worked correctly):

var targetEntity = em.findEntityByKey(entityKey);

So everytime I save my new Entity, a new Entity will be created in my EntityManager. When I reload the page, the entity is flagged correctly and works. The only problem is, that a new entity will be saved everytime I save changes.

Thanks for any help!

Edit 1:

I found the problem and I'm not sure what exactly Breeze expects of me. When my ContextProvider saves the Entity it sends a DB-Update-Command (for all the properties) and then returns. The problem is, that the Id of the saveResult-Object is still the "tempId" and not the real one - so when Breeze on Client-Side receives the object it doesn't find it in the entityManager anymore because the Key-Fixup happened already.

What exactly is Breeze expecting to receive from the saveResult? A representation of the object as it is in the Database at this moment? - would make sense but I don't find it documented.

Edit 2:

It looks like I'm not able to replace the object in the saveWorkState.saveMap (EntityInfo info.Entity is readonly). What I would like to do is create the newly added object and return this object instead of the one that breeze sent me. I have calculated values on the newly created object and the new "real" Id. What the NoDB-Sample seems to do is just overwrite the Id for the newId but any other properties are not changing. Maybe I'm not using this mechanism right?

Was it helpful?

Solution

To make sure, that all EntityInfos that are returned in my SaveResult are the latest representation of the Database I just clear the saveWorkState.SaveMap-Lists

saveWorkState.SaveMap[n].Clear()

and add the new representations

saveWorkState.SaveMap[n].AddRange(newEntityInfos);

and for every Entity that is Added or Modified I create a new EntityInfo with the object that is returned by the Database

    private EntityInfo SaveEntity(List<KeyMapping> keyMap, EntityInfo info) {
            EntityInfo result = info;

            switch (info.EntityState) {
                    case EntityState.Added: {
                                    // CreateInDatabase
                                    // Possible changes in object properties happen (for calculated values)
                                    ...
                                    var newObj = GetObjectAgainFromDatabase(info.Entity);
                                    keyMap.Add(new KeyMapping() { EntityTypeName = bu.RuntimeClass.FullName, TempValue = (MyObject)info.Entity.Id, RealValue = newObj.Id });
                                    result = CreateEntityInfo(newObj, EntityState.Added);
                                    break;
                            }
                    case EntityState.Deleted: {
                                    // Delete in Database
                                    // EntityInfo doesn't have to change
                                    break;
                            }
                    case EntityState.Modified: {
                                    // Update in Database
                                    result = CreateEntityInfo(bu.WrappedPOCO, EntityState.Modified);
                                    break;
                            }
                    default: //EntityState.Detached, EntityState.Unchanged
                            break;
            }

            return result;
    }

Any comments on this solution are welcome!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top