Esempio n. 1
0
        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);
                }
            }
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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);
                }
            }
        }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
 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);
             }
         }
     }
 }
Esempio n. 6
0
 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();
 }
Esempio n. 7
0
        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();
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
 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"));
     }
 }
Esempio n. 10
0
        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));
            }
        }
Esempio n. 11
0
        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));
        }
Esempio n. 12
0
        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"));
            }
        }
Esempio n. 13
0
        /// <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);
            }
        }
Esempio n. 15
0
        /// <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);
        }
Esempio n. 16
0
        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()));
            }
        }
Esempio n. 17
0
 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);
         }
     }
 }
Esempio n. 18
0
        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);
            }
        }
Esempio n. 20
0
        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);
            }
        }
Esempio n. 21
0
        /// <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;
                    }
                }
            }
        }
Esempio n. 22
0
        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;
            }
        }
Esempio n. 23
0
        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;
                    }
                }
            }
        }
Esempio n. 24
0
 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()));
            }
        }
Esempio n. 26
0
        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;
            }
        }
Esempio n. 28
0
        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);
            }
        }
Esempio n. 29
0
        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);
            }
        }
Esempio n. 30
0
        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);
                }
            }
        }