private void HandleUpdateEntity(object entity, string propertyName, object propertyValue) { if (!this.Context.ApplyingChanges) { if (!BindingEntityInfo.IsEntityType(entity.GetType(), this.Context.MaxProtocolVersion)) { this.bindingGraph.GetAncestorEntityForComplexProperty(ref entity, ref propertyName, ref propertyValue); } if (!this.IsDetachedOrDeletedFromContext(entity)) { if (this.EntityChanged != null) { EntityChangedParams arg = new EntityChangedParams(this.Context, entity, propertyName, propertyValue, null, null); if (this.EntityChanged(arg)) { return; } } if (this.IsContextTrackingEntity(entity)) { this.Context.UpdateObject(entity); } } } }
internal void HandleUpdateEntityReference(object source, string sourceProperty, string sourceEntitySet, object target, string targetEntitySet) { if (!this.Context.ApplyingChanges && !this.IsDetachedOrDeletedFromContext(source)) { EntityDescriptor entityDescriptor = (target != null) ? this.Context.GetEntityDescriptor(target) : null; if ((!this.AttachBehavior && ((entityDescriptor == null) || !this.IsContextTrackingLink(source, sourceProperty, target))) && (this.EntityChanged != null)) { EntityChangedParams arg = new EntityChangedParams(this.Context, source, sourceProperty, target, sourceEntitySet, targetEntitySet); if (this.EntityChanged(arg)) { return; } } if (this.IsDetachedOrDeletedFromContext(source)) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_DetachedSource); } entityDescriptor = (target != null) ? this.Context.GetEntityDescriptor(target) : null; if (target != null) { if (entityDescriptor == null) { BindingUtils.ValidateEntitySetName(targetEntitySet, target); if (this.AttachBehavior) { this.Context.AttachTo(targetEntitySet, target); } else { this.Context.AddObject(targetEntitySet, target); } entityDescriptor = this.Context.GetEntityDescriptor(target); } if (!this.IsContextTrackingLink(source, sourceProperty, target)) { if (!this.AttachBehavior) { this.Context.SetLink(source, sourceProperty, target); } else if (entityDescriptor.State != EntityStates.Deleted) { this.Context.AttachLink(source, sourceProperty, target); } } } else { this.Context.SetLink(source, sourceProperty, null); } } }
/// <summary> /// Handle changes to an entity object tracked by the BindingObserver /// </summary> /// <param name="entity">The entity object that has changed.</param> /// <param name="propertyName">The property of the target entity object that has changed.</param> /// <param name="propertyValue">The value of the changed property of the target object.</param> private void HandleUpdateEntity(object entity, string propertyName, object propertyValue) { Debug.Assert(!this.AttachBehavior || this.Context.ApplyingChanges, "Entity updates must not happen during Attach or construction phases, deserialization case is the exception."); if (this.Context.ApplyingChanges) { return; } // For complex types, we will perform notification and update on the closest ancestor entity using the farthest ancestor complex property. if (!BindingEntityInfo.IsEntityType(entity.GetType())) { this.bindingGraph.GetAncestorEntityForComplexProperty(ref entity, ref propertyName, ref propertyValue); } Debug.Assert(entity != null, "entity must be provided for update operations."); Debug.Assert(BindingEntityInfo.IsEntityType(entity.GetType()), "entity must be an entity with keys."); Debug.Assert(!String.IsNullOrEmpty(propertyName) || propertyValue == null, "When propertyName is null no propertyValue should be provided."); // Do not handle update for detached and deleted entities. if (this.IsDetachedOrDeletedFromContext(entity)) { return; } // First give the user code a chance to handle Update operation. if (this.EntityChanged != null) { EntityChangedParams args = new EntityChangedParams( this.Context, entity, propertyName, propertyValue, null, null); if (this.EntityChanged(args)) { return; } } // Default implementation. // The user callback code could detach the entity. if (this.IsContextTrackingEntity(entity)) { // Let UpdateObject check the state of the entity. this.Context.UpdateObject(entity); } }
private void HandleUpdateEntity(object entity, string propertyName, object propertyValue) { Debug.Assert(!this.AttachBehavior || this.Context.ApplyingChanges, "Entity updates must not happen during Attach or construction phases, deserialization case is the exception."); if (this.Context.ApplyingChanges) { return; } if (!BindingEntityInfo.IsEntityType(entity.GetType())) { this.bindingGraph.GetAncestorEntityForComplexProperty(ref entity, ref propertyName, ref propertyValue); } Debug.Assert(entity != null, "entity must be provided for update operations."); Debug.Assert(BindingEntityInfo.IsEntityType(entity.GetType()), "entity must be an entity with keys."); Debug.Assert(!String.IsNullOrEmpty(propertyName) || propertyValue == null, "When propertyName is null no propertyValue should be provided."); if (this.IsDetachedOrDeletedFromContext(entity)) { return; } if (this.EntityChanged != null) { EntityChangedParams args = new EntityChangedParams( this.Context, entity, propertyName, propertyValue, null, null); if (this.EntityChanged(args)) { return; } } if (this.IsContextTrackingEntity(entity)) { this.Context.UpdateObject(entity); } }
internal void HandleUpdateEntityReference( object source, string sourceProperty, string sourceEntitySet, object target, string targetEntitySet) { if (this.Context.ApplyingChanges) { return; } Debug.Assert(source != null, "source can not be null for update operations."); Debug.Assert(BindingEntityInfo.IsEntityType(source.GetType()), "source must be an entity with keys."); Debug.Assert(!String.IsNullOrEmpty(sourceProperty), "sourceProperty must be a non-empty string for update operations."); Debug.Assert(!String.IsNullOrEmpty(sourceEntitySet), "sourceEntitySet must be non-empty string for update operation."); if (this.IsDetachedOrDeletedFromContext(source)) { return; } EntityDescriptor targetDescriptor = target != null?this.Context.GetEntityDescriptor(target) : null; bool contextOperationRequired = !this.AttachBehavior && (targetDescriptor == null || !this.IsContextTrackingLink(source, sourceProperty, target)); if (contextOperationRequired) { if (this.EntityChanged != null) { EntityChangedParams args = new EntityChangedParams( this.Context, source, sourceProperty, target, sourceEntitySet, targetEntitySet); if (this.EntityChanged(args)) { return; } } } if (this.IsDetachedOrDeletedFromContext(source)) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_DetachedSource); } targetDescriptor = target != null?this.Context.GetEntityDescriptor(target) : null; if (target != null) { if (targetDescriptor == null) { BindingUtils.ValidateEntitySetName(targetEntitySet, target); if (this.AttachBehavior) { this.Context.AttachTo(targetEntitySet, target); } else { this.Context.AddObject(targetEntitySet, target); } targetDescriptor = this.Context.GetEntityDescriptor(target); } if (!this.IsContextTrackingLink(source, sourceProperty, target)) { if (this.AttachBehavior) { if (targetDescriptor.State != EntityStates.Deleted) { this.Context.AttachLink(source, sourceProperty, target); } } else { this.Context.SetLink(source, sourceProperty, target); } } } else { Debug.Assert(!this.AttachBehavior, "During attach operations we must never perform operations for null values."); this.Context.SetLink(source, sourceProperty, null); } }
/// <summary>Handle changes to navigation properties of a tracked entity. Perform operations on context to reflect the changes.</summary> /// <param name="source">The source object that reference the target object through a navigation property.</param> /// <param name="sourceProperty">The navigation property in the source object that reference the target object.</param> /// <param name="sourceEntitySet">The entity set of the source object.</param> /// <param name="target">The target entity.</param> /// <param name="targetEntitySet">The entity set name of the target object.</param> internal void HandleUpdateEntityReference( object source, string sourceProperty, string sourceEntitySet, object target, string targetEntitySet) { if (this.Context.ApplyingChanges) { return; } Debug.Assert(source != null, "source can not be null for update operations."); Debug.Assert(BindingEntityInfo.IsEntityType(source.GetType()), "source must be an entity with keys."); Debug.Assert(!String.IsNullOrEmpty(sourceProperty), "sourceProperty must be a non-empty string for update operations."); Debug.Assert(!String.IsNullOrEmpty(sourceEntitySet), "sourceEntitySet must be non-empty string for update operation."); // Do not handle update for detached and deleted entities. if (this.IsDetachedOrDeletedFromContext(source)) { return; } // Do we need an operation on context to handle the Update operation. EntityDescriptor targetDescriptor = target != null?this.Context.GetEntityDescriptor(target) : null; // Following are the conditions where context operation is required: // 1. Not a call to Load or constructions i.e. we have Add behavior and not Attach behavior // 2. Target entity is not being tracked // 3. Target is being tracked but there is no link between the source and target entity bool contextOperationRequired = !this.AttachBehavior && (targetDescriptor == null || !this.IsContextTrackingLink(source, sourceProperty, target)); if (contextOperationRequired) { // First give the user code a chance to handle Update link operation. if (this.EntityChanged != null) { EntityChangedParams args = new EntityChangedParams( this.Context, source, sourceProperty, target, sourceEntitySet, targetEntitySet); if (this.EntityChanged(args)) { return; } } } // The user callback code could detach the source. if (this.IsDetachedOrDeletedFromContext(source)) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_DetachedSource); } // Default implementation. targetDescriptor = target != null?this.Context.GetEntityDescriptor(target) : null; if (target != null) { if (targetDescriptor == null) { // If the entity set name is not known, then we must throw since we need to know the // entity set in order to add/attach the referenced object to it's entity set. BindingUtils.ValidateEntitySetName(targetEntitySet, target); if (this.AttachBehavior) { this.Context.AttachTo(targetEntitySet, target); } else { this.Context.AddObject(targetEntitySet, target); } targetDescriptor = this.Context.GetEntityDescriptor(target); } // if the entity is already tracked, then just set/attach the link. However, do // not try to attach the link if the target is in Deleted state. if (!this.IsContextTrackingLink(source, sourceProperty, target)) { if (this.AttachBehavior) { if (targetDescriptor.State != EntityStates.Deleted) { this.Context.AttachLink(source, sourceProperty, target); } } else { this.Context.SetLink(source, sourceProperty, target); } } } else { Debug.Assert(!this.AttachBehavior, "During attach operations we must never perform operations for null values."); // The target could be null in which case we just need to set the link to null. this.Context.SetLink(source, sourceProperty, null); } }