private void AddFromProperties(object entity) { foreach (BindingEntityInfo.BindingPropertyInfo info in BindingEntityInfo.GetObservableProperties(entity.GetType(), this.observer.Context.MaxProtocolVersion)) { object target = info.PropertyInfo.GetValue(entity); if (target != null) { switch (info.PropertyKind) { case BindingPropertyKind.BindingPropertyKindEntity: { this.AddEntity(entity, info.PropertyInfo.PropertyName, target, null, entity); continue; } case BindingPropertyKind.BindingPropertyKindDataServiceCollection: { this.AddDataServiceCollection(entity, info.PropertyInfo.PropertyName, target, null); continue; } case BindingPropertyKind.BindingPropertyKindPrimitiveOrComplexCollection: { this.AddPrimitiveOrComplexCollection(entity, info.PropertyInfo.PropertyName, target, info.PropertyInfo.PrimitiveOrComplexCollectionItemType); continue; } } this.AddComplexObject(entity, info.PropertyInfo.PropertyName, target); } } }
private object GetCollectionInstance(ClientPropertyAnnotation property, out bool instanceCreated) { instanceCreated = false; object obj2 = property.GetValue(this.entity); if (obj2 != null) { return(obj2); } instanceCreated = true; Type propertyType = property.PropertyType; if (BindingEntityInfo.IsDataServiceCollection(propertyType, base.RequestInfo.MaxProtocolVersion)) { object[] args = new object[2]; args[1] = TrackingMode.None; return(Activator.CreateInstance(WebUtil.GetDataServiceCollectionOfT(new Type[] { property.EntityCollectionItemType }), args)); } Type c = typeof(List <>).MakeGenericType(new Type[] { property.EntityCollectionItemType }); if (!propertyType.IsAssignableFrom(c)) { c = propertyType; } return(Activator.CreateInstance(c)); }
private void OnAddToCollection( NotifyCollectionChangedEventArgs eventArgs, object source, String sourceProperty, String targetEntitySet, object collection) { Debug.Assert(collection != null, "Must have a valid collection to which entities are added."); if (eventArgs.NewItems != null) { foreach (object target in eventArgs.NewItems) { if (target == null) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNull("Add")); } if (!BindingEntityInfo.IsEntityType(target.GetType())) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNotEntity("Add")); } this.bindingGraph.AddEntity( source, sourceProperty, target, targetEntitySet, collection); } } }
/// <summary> /// Tries to get the value of a property and corresponding BindingPropertyInfo or ClientPropertyAnnotation if the property exists /// </summary> /// <param name="source">Source object whose property needs to be read</param> /// <param name="sourceProperty">Name of the source object property</param> /// <param name="model">The client model.</param> /// <param name="bindingPropertyInfo">BindingPropertyInfo corresponding to <paramref name="sourceProperty"/></param> /// <param name="clientProperty">Instance of ClientProperty corresponding to <paramref name="sourceProperty"/></param> /// <param name="propertyValue">Value of the property</param> /// <returns>true if the property exists and the value was read; otherwise false.</returns> internal static bool TryGetPropertyValue(object source, string sourceProperty, ClientEdmModel model, out BindingPropertyInfo bindingPropertyInfo, out ClientPropertyAnnotation clientProperty, out object propertyValue) { Type sourceType = source.GetType(); bindingPropertyInfo = BindingEntityInfo.GetObservableProperties(sourceType, model) .SingleOrDefault(x => x.PropertyInfo.PropertyName == sourceProperty); bool propertyFound = bindingPropertyInfo != null; // bindingPropertyInfo is null for primitive properties. if (!propertyFound) { clientProperty = BindingEntityInfo.GetClientType(sourceType, model) .GetProperty(sourceProperty, true); propertyFound = clientProperty != null; if (!propertyFound) { propertyValue = null; } else { propertyValue = clientProperty.GetValue(source); } } else { clientProperty = null; propertyValue = bindingPropertyInfo.PropertyInfo.GetValue(source); } return(propertyFound); }
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); } } } }
public void RemoveNonTrackedEntities() { foreach (object obj2 in this.graph.Select(o => BindingEntityInfo.IsEntityType(o.GetType(), this.observer.Context.MaxProtocolVersion) && !this.observer.IsContextTrackingEntity(o))) { this.graph.ClearEdgesForVertex(this.graph.LookupVertex(obj2)); } this.RemoveUnreachableVertices(); }
public void RemoveNonTrackedEntities() { foreach (var entity in this.graph.Select(o => BindingEntityInfo.IsEntityType(o.GetType()) && !this.observer.IsContextTrackingEntity(o))) { this.graph.ClearEdgesForVertex(this.graph.LookupVertex(entity)); } this.RemoveUnreachableVertices(); }
private bool IsDetachedOrDeletedFromContext(object entity) { Debug.Assert(entity != null, "entity must be provided."); Debug.Assert(BindingEntityInfo.IsEntityType(entity.GetType()), "entity must be an entity with keys."); EntityDescriptor descriptor = this.Context.GetEntityDescriptor(entity); return(descriptor == null || descriptor.State == EntityStates.Deleted); }
private void ValidateDataServiceCollectionItem(object target) { if (target == null) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNull("Remove")); } if (!BindingEntityInfo.IsEntityType(target.GetType(), this.Context.MaxProtocolVersion)) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNotEntity("Remove")); } }
internal static void VerifyObserverNotPresent <T>(object oec, string sourceProperty, Type sourceType) { Debug.Assert(BindingEntityInfo.IsDataServiceCollection(oec.GetType()), "Must be an DataServiceCollection."); DataServiceCollection <T> typedCollection = oec as DataServiceCollection <T>; if (typedCollection.Observer != null) { throw new InvalidOperationException(Strings.DataBinding_CollectionPropertySetterValueHasObserver(sourceProperty, sourceType)); } }
private bool IsContextTrackingLink(object source, string sourceProperty, object target) { Debug.Assert(source != null, "source entity must be provided."); Debug.Assert(BindingEntityInfo.IsEntityType(source.GetType()), "source must be an entity with keys."); Debug.Assert(!String.IsNullOrEmpty(sourceProperty), "sourceProperty must be provided."); Debug.Assert(target != null, "target entity must be provided."); Debug.Assert(BindingEntityInfo.IsEntityType(target.GetType()), "target must be an entity with keys."); return(this.Context.GetLinkDescriptor(source, sourceProperty, target) != default(LinkDescriptor)); }
private void ValidateCollectionItem(object target) { if (target == null) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNull("Remove")); } if (!BindingEntityInfo.IsEntityType(target.GetType())) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNotEntity("Remove")); } }
/// <summary> /// Determine if the specified type is an entity type. /// </summary> /// <param name="type">An object type specifier.</param> /// <param name="model">The client model.</param> /// <returns>true if the type is an entity type; otherwise false.</returns> internal static bool IsEntityType(Type type, ClientEdmModel model) { Debug.Assert(type != null, "Argument 'type' cannot be null."); metadataCacheLock.EnterReadLock(); try { if (knownNonEntityTypes.Contains(type)) { return(false); } } finally { metadataCacheLock.ExitReadLock(); } bool isEntityType; try { if (BindingEntityInfo.IsDataServiceCollection(type, model)) { return(false); } isEntityType = ClientTypeUtil.TypeOrElementTypeIsEntity(type); } catch (InvalidOperationException) { isEntityType = false; } if (!isEntityType) { metadataCacheLock.EnterWriteLock(); try { if (!knownNonEntityTypes.Contains(type)) { knownNonEntityTypes.Add(type); } } finally { metadataCacheLock.ExitWriteLock(); } } return(isEntityType); }
/// <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); } }
/// <summary> /// Removes the <paramref name="item"/> from the binding graph /// </summary> /// <param name="item">Item to remove</param> /// <param name="parent">Parent of the <paramref name="item"/></param> /// <param name="parentProperty">Parent property that refers to <paramref name="item"/></param> public void Remove(object item, object parent, string parentProperty) { Vertex vertexToRemove = this.graph.LookupVertex(item); if (vertexToRemove == null) { return; } Debug.Assert(!vertexToRemove.IsRootCollection, "Root collections are never removed"); // Parent will always be non-null for deletes from collections, this will include // both root and child collections. For root collections, parentProperty will be null. Debug.Assert(parent != null, "Parent has to be present."); // When parentProperty is null, parent is itself a root collection if (parentProperty != null) { BindingEntityInfo.BindingPropertyInfo bpi = BindingEntityInfo.GetObservableProperties(parent.GetType()) .Single(p => p.PropertyInfo.PropertyName == parentProperty); Debug.Assert(bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindCollection, "parentProperty must refer to an DataServiceCollection"); parent = bpi.PropertyInfo.GetValue(parent); } object source = null; string sourceProperty = null; string sourceEntitySet = null; string targetEntitySet = null; this.GetEntityCollectionInfo( parent, out source, out sourceProperty, out sourceEntitySet, out targetEntitySet); targetEntitySet = BindingEntityInfo.GetEntitySet(item, targetEntitySet); this.observer.HandleDeleteEntity( source, sourceProperty, sourceEntitySet, parent as ICollection, item, targetEntitySet); this.graph.RemoveEdge(parent, item, null); }
internal static string GetEntitySet( object target, string targetEntitySet) { Debug.Assert(target != null, "Argument 'target' cannot be null."); Debug.Assert(BindingEntityInfo.IsEntityType(target.GetType()), "Argument 'target' must be an entity type."); if (!String.IsNullOrEmpty(targetEntitySet)) { return(targetEntitySet); } else { return(BindingEntityInfo.GetEntitySetAttribute(target.GetType())); } }
private void OnAddToDataServiceCollection(NotifyCollectionChangedEventArgs eventArgs, object source, string sourceProperty, string targetEntitySet, object collection) { if (eventArgs.NewItems != null) { foreach (object obj2 in eventArgs.NewItems) { if (obj2 == null) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNull("Add")); } if (!BindingEntityInfo.IsEntityType(obj2.GetType(), this.Context.MaxProtocolVersion)) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_ArrayItemNotEntity("Add")); } this.bindingGraph.AddEntity(source, sourceProperty, obj2, targetEntitySet, collection); } } }
internal static object GetPropertyValue(object source, string sourceProperty, out BindingPropertyInfo bindingPropertyInfo) { Type sourceType = source.GetType(); bindingPropertyInfo = BindingEntityInfo.GetObservableProperties(sourceType) .SingleOrDefault(x => x.PropertyInfo.PropertyName == sourceProperty); if (bindingPropertyInfo == null) { return(BindingEntityInfo.GetClientType(sourceType) .GetProperty(sourceProperty, false) .GetValue(source)); } else { return(bindingPropertyInfo.PropertyInfo.GetValue(source)); } }
/// <summary> /// Determine if the specified type is an entity type. /// </summary> /// <param name="type">An object type specifier.</param> /// <returns>True if the type is an entity type; otherwise false.</returns> internal static bool IsEntityType(Type type) { Debug.Assert(type != null, "Argument 'type' cannot be null."); metadataCacheLock.EnterReadLock(); try { if (knownNonEntityTypes.Contains(type)) { return(false); } } finally { metadataCacheLock.ExitReadLock(); } try { if (BindingEntityInfo.IsDataServiceCollection(type)) { return(false); } return(ClientType.Create(type).IsEntityType); } catch (InvalidOperationException) { metadataCacheLock.EnterWriteLock(); try { if (!knownNonEntityTypes.Contains(type)) { knownNonEntityTypes.Add(type); } } finally { metadataCacheLock.ExitWriteLock(); } return(false); } }
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); } }
/// <summary>Add items to the graph, from the <paramref name="entity"/> object's properties</summary> /// <param name="entity">Object whose properties are to be explored</param> private void AddFromProperties(object entity) { // Once the entity is attached to the graph, we need to traverse all it's properties // and add related entities and collections to this entity. foreach (BindingEntityInfo.BindingPropertyInfo bpi in BindingEntityInfo.GetObservableProperties(entity.GetType())) { object propertyValue = bpi.PropertyInfo.GetValue(entity); if (propertyValue != null) { switch (bpi.PropertyKind) { case BindingPropertyKind.BindingPropertyKindCollection: this.AddCollection( entity, bpi.PropertyInfo.PropertyName, propertyValue, null); break; case BindingPropertyKind.BindingPropertyKindEntity: this.AddEntity( entity, bpi.PropertyInfo.PropertyName, propertyValue, null, entity); break; default: Debug.Assert(bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindComplex, "Must be complex type if PropertyKind is not entity or collection."); this.AddComplexProperty( entity, bpi.PropertyInfo.PropertyName, propertyValue); break; } } } }
internal void StartTracking <T>(DataServiceCollection <T> collection, string collectionEntitySet) { Debug.Assert(collection != null, "Only constructed collections are tracked."); if (!BindingEntityInfo.IsEntityType(typeof(T))) { throw new ArgumentException(Strings.DataBinding_DataServiceCollectionArgumentMustHaveEntityType(typeof(T))); } try { this.AttachBehavior = true; this.bindingGraph.AddCollection(null, null, collection, collectionEntitySet); } finally { this.AttachBehavior = false; } }
private void AddFromProperties(object entity) { foreach (BindingEntityInfo.BindingPropertyInfo bpi in BindingEntityInfo.GetObservableProperties(entity.GetType())) { object propertyValue = bpi.PropertyInfo.GetValue(entity); if (propertyValue != null) { switch (bpi.PropertyKind) { case BindingPropertyKind.BindingPropertyKindCollection: this.AddCollection( entity, bpi.PropertyInfo.PropertyName, propertyValue, null); break; case BindingPropertyKind.BindingPropertyKindEntity: this.AddEntity( entity, bpi.PropertyInfo.PropertyName, propertyValue, null, entity); break; default: Debug.Assert(bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindComplex, "Must be complex type if PropertyKind is not entity or collection."); this.AddComplexProperty( entity, bpi.PropertyInfo.PropertyName, propertyValue); break; } } } }
private void StartTracking(DataServiceContext context, IEnumerable <T> items, string entitySet, Func <EntityChangedParams, bool> entityChanged, Func <EntityCollectionChangedParams, bool> collectionChanged) { if (!BindingEntityInfo.IsEntityType(typeof(T), context.MaxProtocolVersion)) { throw new ArgumentException(Strings.DataBinding_DataServiceCollectionArgumentMustHaveEntityType(typeof(T))); } this.observer = new BindingObserver(context, entityChanged, collectionChanged); if (items != null) { try { this.InternalLoadCollection(items); } catch { this.observer = null; throw; } } this.observer.StartTracking <T>((DataServiceCollection <T>) this, entitySet); this.rootCollection = true; }
/// <summary> /// Get the entity set name for the target entity object. /// </summary> /// <param name="target">An entity object.</param> /// <param name="targetEntitySet">The 'currently known' entity set name for the target object.</param> /// <returns>The entity set name for the target object.</returns> /// <remarks> /// Allow user code to provide the entity set name. If user code does not provide the entity set name, then /// this method will get the entity set name from the value of the EntitySetAttribute. /// The 'currently known' entity set name for top level collections can be provided through OEC constructor /// </remarks> internal static string GetEntitySet( object target, string targetEntitySet) { Debug.Assert(target != null, "Argument 'target' cannot be null."); Debug.Assert(BindingEntityInfo.IsEntityType(target.GetType()), "Argument 'target' must be an entity type."); // Here's the rules in order of priority for resolving entity set name // 1. EntitySet name passed in the constructor or extension methods of DataServiceCollection // 2. EntitySet name specified in the EntitySet attribute by the code gen. {Remember this attribute is // not generated in case of MEST) if (!String.IsNullOrEmpty(targetEntitySet)) { return(targetEntitySet); } else { // If there is not a 'currently known' entity set name to validate against, then there must be // EntitySet attribute on the entity type return(BindingEntityInfo.GetEntitySetAttribute(target.GetType())); } }
public bool AddEntity(object source, string sourceProperty, object target, string targetEntitySet, object edgeSource) { Vertex vertex = this.graph.LookupVertex(edgeSource); Vertex vertex2 = null; bool flag = false; if (target != null) { vertex2 = this.graph.LookupVertex(target); if (vertex2 == null) { vertex2 = this.graph.AddVertex(target); vertex2.EntitySet = BindingEntityInfo.GetEntitySet(target, targetEntitySet, this.observer.Context.MaxProtocolVersion); if (!this.AttachEntityOrComplexObjectNotification(target)) { throw new InvalidOperationException(System.Data.Services.Client.Strings.DataBinding_NotifyPropertyChangedNotImpl(target.GetType())); } flag = true; } if (this.graph.ExistsEdge(edgeSource, target, vertex.IsDataServiceCollection ? null : sourceProperty)) { throw new InvalidOperationException(System.Data.Services.Client.Strings.DataBinding_EntityAlreadyInCollection(target.GetType())); } this.graph.AddEdge(edgeSource, target, vertex.IsDataServiceCollection ? null : sourceProperty); } if (!vertex.IsDataServiceCollection) { this.observer.HandleUpdateEntityReference(source, sourceProperty, vertex.EntitySet, target, (vertex2 == null) ? null : vertex2.EntitySet); } else { this.observer.HandleAddEntity(source, sourceProperty, (vertex.Parent != null) ? vertex.Parent.EntitySet : null, edgeSource as ICollection, target, vertex2.EntitySet); } if (flag) { this.AddFromProperties(target); } return(flag); }
/// <summary>Start tracking the specified DataServiceCollection.</summary> /// <typeparam name="T">An entity type.</typeparam> /// <param name="collection">An DataServiceCollection.</param> /// <param name="collectionEntitySet">The entity set of the elements in <paramref name="collection"/>.</param> internal void StartTracking <T>(DataServiceCollection <T> collection, string collectionEntitySet) { Debug.Assert(collection != null, "Only constructed collections are tracked."); // Verify that T corresponds to an entity type. if (!BindingEntityInfo.IsEntityType(typeof(T))) { throw new ArgumentException(Strings.DataBinding_DataServiceCollectionArgumentMustHaveEntityType(typeof(T))); } try { this.AttachBehavior = true; // Recursively traverse the entire object graph under the root collection. this.bindingGraph.AddCollection(null, null, collection, collectionEntitySet); } finally { this.AttachBehavior = false; } }
public void RemoveDataServiceCollectionItem(object item, object parent, string parentProperty) { Func <BindingEntityInfo.BindingPropertyInfo, bool> predicate = null; if (this.graph.LookupVertex(item) != null) { if (parentProperty != null) { if (predicate == null) { predicate = p => p.PropertyInfo.PropertyName == parentProperty; } parent = BindingEntityInfo.GetObservableProperties(parent.GetType(), this.observer.Context.MaxProtocolVersion).Single <BindingEntityInfo.BindingPropertyInfo>(predicate).PropertyInfo.GetValue(parent); } object source = null; string sourceProperty = null; string sourceEntitySet = null; string targetEntitySet = null; this.GetDataServiceCollectionInfo(parent, out source, out sourceProperty, out sourceEntitySet, out targetEntitySet); targetEntitySet = BindingEntityInfo.GetEntitySet(item, targetEntitySet, this.observer.Context.MaxProtocolVersion); this.observer.HandleDeleteEntity(source, sourceProperty, sourceEntitySet, parent as ICollection, item, targetEntitySet); this.graph.RemoveEdge(parent, item, null); } }
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); } }
internal void HandleDeleteEntity( object source, string sourceProperty, string sourceEntitySet, ICollection collection, object target, string targetEntitySet) { if (this.Context.ApplyingChanges) { return; } Debug.Assert( (source == null && sourceProperty == null) || (source != null && !String.IsNullOrEmpty(sourceProperty)), "source and sourceProperty should either both be present or both be absent."); Debug.Assert(target != null, "target must be provided by the caller."); Debug.Assert(BindingEntityInfo.IsEntityType(target.GetType()), "target must be an entity type."); Debug.Assert(!this.AttachBehavior, "AttachBehavior is only allowed during Construction and Load when this method should never be entered."); if (source != null && this.IsDetachedOrDeletedFromContext(source)) { return; } bool contextOperationRequired = this.IsContextTrackingEntity(target) && !this.DetachBehavior; if (contextOperationRequired) { if (this.CollectionChanged != null) { EntityCollectionChangedParams args = new EntityCollectionChangedParams( this.Context, source, sourceProperty, sourceEntitySet, collection, target, targetEntitySet, NotifyCollectionChangedAction.Remove); if (this.CollectionChanged(args)) { return; } } } if (source != null && !this.IsContextTrackingEntity(source)) { throw new InvalidOperationException(Strings.DataBinding_BindingOperation_DetachedSource); } if (this.IsContextTrackingEntity(target)) { if (this.DetachBehavior) { this.Context.Detach(target); } else { this.Context.DeleteObject(target); } } }