/// <summary>use location from header to generate initial edit and identity</summary> /// <param name="entity">entity in added state</param> /// <param name="identity">identity as specified in the response header - location header or OData-EntityId header.</param> /// <param name="editLink">editlink as specified in the response header - location header.</param> internal void AttachLocation(object entity, Uri identity, Uri editLink) { Debug.Assert(entity != null, "null != entity"); Debug.Assert(editLink != null, "editLink != null"); this.EnsureIdentityToResource(); // resource.State == EntityState.Added or Unchanged for second pass of media link EntityDescriptor resource = this.entityDescriptors[entity]; // make sure we got the right one - server could override identity and we may be tracking another one already. this.ValidateDuplicateIdentity(identity, resource); this.DetachResourceIdentity(resource); // While processing the response, we need to find out if the given resource was inserted deep // If it was, then we need to change the link state from added to unchanged if (resource.IsDeepInsert) { LinkDescriptor end = this.bindings[resource.GetRelatedEnd()]; end.State = EntityStates.Unchanged; } resource.Identity = identity; // always attach the identity resource.EditLink = editLink; // scenario: successfully batch (1) add a new entity and (2) delete an existing entity where the new entity has the same identity as deleted entity // where the SaveChanges pass1 will now associate existing identity with new entity // but pass2 for the deleted entity will not blindly remove the identity that is now associated with the new identity this.identityToDescriptor[identity] = resource; }
/// <summary>response materialization has an identity to attach to the inserted object</summary> /// <param name="entityDescriptorFromMaterializer">entity descriptor containing all the information about the entity from the response.</param> /// <param name="metadataMergeOption">mergeOption based on which EntityDescriptor will be merged.</param> internal override void AttachIdentity(EntityDescriptor entityDescriptorFromMaterializer, MergeOption metadataMergeOption) { // insert->unchanged Debug.Assert(entityDescriptorFromMaterializer != null, "entityDescriptorFromMaterializer != null"); this.EnsureIdentityToResource(); // resource.State == EntityState.Added or Unchanged for second pass of media link EntityDescriptor trackedEntityDescriptor = this.entityDescriptors[entityDescriptorFromMaterializer.Entity]; // make sure we got the right one - server could override identity and we may be tracking another one already. this.ValidateDuplicateIdentity(entityDescriptorFromMaterializer.Identity, trackedEntityDescriptor); this.DetachResourceIdentity(trackedEntityDescriptor); // While processing the response, we need to find out if the given resource was inserted deep // If it was, then we need to change the link state from added to unchanged if (trackedEntityDescriptor.IsDeepInsert) { LinkDescriptor end = this.bindings[trackedEntityDescriptor.GetRelatedEnd()]; end.State = EntityStates.Unchanged; } trackedEntityDescriptor.Identity = entityDescriptorFromMaterializer.Identity; // always attach the identity AtomMaterializerLog.MergeEntityDescriptorInfo(trackedEntityDescriptor, entityDescriptorFromMaterializer, true /*mergeInfo*/, metadataMergeOption); trackedEntityDescriptor.State = EntityStates.Unchanged; trackedEntityDescriptor.PropertiesToSerialize.Clear(); // scenario: successfully (1) delete an existing entity and (2) add a new entity where the new entity has the same identity as deleted entity // where the SaveChanges pass1 will now associate existing identity with new entity // but pass2 for the deleted entity will not blindly remove the identity that is now associated with the new identity this.identityToDescriptor[entityDescriptorFromMaterializer.Identity] = trackedEntityDescriptor; }