Пример #1
0
        private void CompareBagPropertyWithNullOrEmpty(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues)
        {
            List <NamedValue> exactMatches = namedValues.Where(nv => nv.Name == propertyPath).ToList();

            if (!exactMatches.Any())
            {
                return;
            }

            ExceptionUtilities.Assert(exactMatches.Count == 1, "Should only find at most one property path {0} when looking for null or empty value", propertyPath);

            QueryCollectionValue actualQueryBagValue = instance.GetCollectionValue(memberProperty.Name);
            NamedValue           expectedBagValue    = exactMatches.Single();

            if (expectedBagValue.Value == null)
            {
                this.WriteErrorIfNotNull(propertyPath, actualQueryBagValue);
                this.unusedNamedValuePaths.Remove(propertyPath);
            }
            else if (expectedBagValue.Value == EmptyData.Value)
            {
                if (!this.WriteErrorIfNull(propertyPath, actualQueryBagValue))
                {
                    this.WriteErrorIfNotEqual(propertyPath, actualQueryBagValue.Elements.Count, 0, "Expected zero elements in BagProperty");
                    this.unusedNamedValuePaths.Remove(propertyPath);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Removes the the entity with the given key from the given the given property on the given structural value
        /// </summary>
        /// <param name="keyToRemove">The key of the entity to remove</param>
        /// <param name="related">The structural value to remove from</param>
        /// <param name="navigation">The property to remove from</param>
        private void RemoveFromNavigationProperty(EntityDataKey keyToRemove, QueryStructuralValue related, NavigationProperty navigation)
        {
            if (navigation.ToAssociationEnd.Multiplicity == EndMultiplicity.Many)
            {
                var collection = related.GetCollectionValue(navigation.Name);

                // remove the element with the given key from the collection, if it is present
                foreach (var element in collection.Elements.Cast <QueryStructuralValue>().ToList())
                {
                    if (this.GetEntityKey(element).Equals(keyToRemove))
                    {
                        collection.Elements.Remove(element);
                    }
                }
            }
            else
            {
                // if the value's key matches, set it to null
                var value = related.GetStructuralValue(navigation.Name);
                if (!value.IsNull && this.GetEntityKey(value).Equals(keyToRemove))
                {
                    related.SetValue(navigation.Name, value.Type.NullValue);
                }
            }
        }
Пример #3
0
        private void ComparePrimitiveBag(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues)
        {
            int i = 0;

            var collection = instance.GetCollectionValue(memberProperty.Name);

            if (!this.WriteErrorIfNull(propertyPath, collection))
            {
                List <NamedValue> primitiveItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
                while (primitiveItemNamedValues.Any())
                {
                    if (i < collection.Elements.Count)
                    {
                        var scalarQueryValue = collection.Elements[i] as QueryScalarValue;
                        ExceptionUtilities.Assert(primitiveItemNamedValues.Count() < 2, "Should not get more than one value for a primitive Bag item for path '{0}'", propertyPath + "." + i);
                        var value = primitiveItemNamedValues.Single();
                        this.WriteErrorIfNotEqual(propertyPath, value.Value, scalarQueryValue);
                        this.unusedNamedValuePaths.Remove(value.Name);
                    }

                    i++;
                    primitiveItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
                }

                this.WriteErrorIfNotEqual(propertyPath, collection.Elements.Count, i, "The number of expected items '{0}' does not match the actual '{1}' for propertyPath {2}", collection.Elements.Count, i, propertyPath);
            }
        }
Пример #4
0
        private void SetCollectionProperty(QueryStructuralValue instance, QueryProperty memberProperty, List <QueryValue> collectionElements)
        {
            QueryCollectionValue queryCollectionValue = instance.GetCollectionValue(memberProperty.Name);

            queryCollectionValue.Elements.Clear();
            foreach (QueryValue queryValue in collectionElements)
            {
                queryCollectionValue.Elements.Add(queryValue);
            }

            instance.SetValue(memberProperty.Name, queryCollectionValue);
        }
        private void ExpandRelated(Dictionary<QueryStructuralValue, QueryStructuralValue> identityMap, QueryValue item, string[] splitPath, int position, IEnumerable<string> expandedPath, IEnumerable<string> selectedPath)
        {
            QueryStructuralValue qsv = item as QueryStructuralValue;
            if (qsv == null)
            {
                return;
            }

            if (position >= splitPath.Length)
            {
                return;
            }

            var memberName = splitPath[position];
            var member = qsv.Type.Properties.SingleOrDefault(c => c.Name == memberName);
            if (member == null)
            {
                return;
            }

            // do not expand if the selected paths don't contain the expand value
            if (selectedPath.Count() > 0 && !selectedPath.Contains(member.Name))
            {
                return;
            }

            var clone = this.CloneStructuralValue(identityMap, qsv);

            if (member.PropertyType is QueryCollectionType)
            {
                var oldValue = qsv.GetCollectionValue(memberName);

                clone.SetValue(memberName, this.CloneCollectionValue(identityMap, oldValue));
                if (!oldValue.IsNull)
                {
                    foreach (var e in oldValue.Elements)
                    {
                        this.ExpandRelated(identityMap, e, splitPath, position + 1, expandedPath, selectedPath);
                    }
                }
            }
            else if (member.PropertyType is QueryStructuralType)
            {
                var oldValue = qsv.GetStructuralValue(memberName);
                var newValue = this.CloneStructuralValue(identityMap, oldValue);
                clone.SetValue(memberName, newValue);
                this.ExpandRelated(identityMap, oldValue, splitPath, position + 1, expandedPath, selectedPath);
            }
        }
Пример #6
0
        private void FixupNavigationProperty(QueryStructuralValue fromValue, QueryStructuralValue toValue, string propertyName)
        {
            var propertyType = fromValue.Type.Properties.Where(p => p.Name == propertyName).Single().PropertyType;

            if (propertyType is QueryEntityType)
            {
                fromValue.SetValue(propertyName, toValue);
            }
            else
            {
                ExceptionUtilities.Assert(propertyType is QueryCollectionType, "Expecting collection type.");
                var currentCollection = fromValue.GetCollectionValue(propertyName);
                if (!currentCollection.Elements.Contains(toValue))
                {
                    currentCollection.Elements.Add(toValue);
                }

                fromValue.SetValue(propertyName, currentCollection);
            }
        }
Пример #7
0
        /// <summary>
        /// Removes the given entity from the query data set
        /// Will remove all references to the entity if the provider is relational, and will delete any related objects that are marked as cascade-delete
        /// </summary>
        /// <param name="entity">The entity to remove</param>
        private void RemoveEntity(QueryStructuralValue entity)
        {
            ExceptionUtilities.CheckArgumentNotNull(entity, "entity");
            QueryEntityType entityType = entity.Type as QueryEntityType;

            ExceptionUtilities.CheckObjectNotNull(entityType, "Value was not an entity");

            // remove it from the top level set
            this.QueryDataSet[entityType.EntitySet.Name].Elements.Remove(entity);

            // remove all other references to this entity
            this.RemoveAllReferences(entityType, entity);

            // if any of this entity's relationships have cascading deletes, we need to emulate them
            foreach (var navigation in entityType.EntityType.AllNavigationProperties)
            {
                if (navigation.ToAssociationEnd.DeleteBehavior == OperationAction.Cascade)
                {
                    if (navigation.ToAssociationEnd.Multiplicity == EndMultiplicity.Many)
                    {
                        var collection = entity.GetCollectionValue(navigation.Name);

                        // recurse into the elements
                        foreach (var related in collection.Elements.Cast <QueryStructuralValue>())
                        {
                            this.RemoveEntity(related);
                        }
                    }
                    else
                    {
                        // recurse into the reference
                        var reference = entity.GetStructuralValue(navigation.Name);
                        if (!reference.IsNull)
                        {
                            this.RemoveEntity(reference);
                        }
                    }
                }
            }
        }
Пример #8
0
        private void CompareComplexBag(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues)
        {
            int i = 0;

            var collection = instance.GetCollectionValue(memberProperty.Name);

            if (!this.WriteErrorIfNull(propertyPath, collection))
            {
                List <NamedValue> complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                while (complexInstanceNamedValues.Any())
                {
                    if (i < collection.Elements.Count)
                    {
                        var complexValue = collection.Elements[i] as QueryStructuralValue;
                        this.CompareValues(complexValue, complexInstanceNamedValues, propertyPath + "." + i);
                    }

                    i++;
                    complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                }

                this.WriteErrorIfNotEqual(propertyPath, collection.Elements.Count, i, "The number of expected items '{0}' does not match the actual '{1}' for propertyPath {2}", collection.Elements.Count, i, propertyPath);
            }
        }
        private void CompareBagPropertyWithNullOrEmpty(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues)
        {
            List<NamedValue> exactMatches = namedValues.Where(nv => nv.Name == propertyPath).ToList();

            if (!exactMatches.Any())
            {
                return;
            }

            ExceptionUtilities.Assert(exactMatches.Count == 1, "Should only find at most one property path {0} when looking for null or empty value", propertyPath);
            
            QueryCollectionValue actualQueryBagValue = instance.GetCollectionValue(memberProperty.Name);
            NamedValue expectedBagValue = exactMatches.Single();

            if (expectedBagValue.Value == null)
            {
                this.WriteErrorIfNotNull(propertyPath, actualQueryBagValue);
                this.unusedNamedValuePaths.Remove(propertyPath);
            }
            else if (expectedBagValue.Value == EmptyData.Value)
            {
                if (!this.WriteErrorIfNull(propertyPath, actualQueryBagValue))
                {
                    this.WriteErrorIfNotEqual(propertyPath, actualQueryBagValue.Elements.Count, 0, "Expected zero elements in BagProperty");
                    this.unusedNamedValuePaths.Remove(propertyPath);
                }
            }
        }
        private void ComparePrimitiveBag(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues)
        {
            int i = 0;

            var collection = instance.GetCollectionValue(memberProperty.Name);

            if (!this.WriteErrorIfNull(propertyPath, collection))
            {
                List<NamedValue> primitiveItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
                while (primitiveItemNamedValues.Any())
                {                    
                    if (i < collection.Elements.Count)
                    {
                        var scalarQueryValue = collection.Elements[i] as QueryScalarValue;
                        ExceptionUtilities.Assert(primitiveItemNamedValues.Count() < 2, "Should not get more than one value for a primitive Bag item for path '{0}'", propertyPath + "." + i);
                        var value = primitiveItemNamedValues.Single();
                        this.WriteErrorIfNotEqual(propertyPath, value.Value, scalarQueryValue);
                        this.unusedNamedValuePaths.Remove(value.Name);
                    }

                    i++;
                    primitiveItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
                }

                this.WriteErrorIfNotEqual(propertyPath, collection.Elements.Count, i, "The number of expected items '{0}' does not match the actual '{1}' for propertyPath {2}", collection.Elements.Count, i, propertyPath);
            }
        }
        private void CompareComplexBag(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues)
        {
            int i = 0;

            var collection = instance.GetCollectionValue(memberProperty.Name);

            if (!this.WriteErrorIfNull(propertyPath, collection))
            {
                List<NamedValue> complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                while (complexInstanceNamedValues.Any())
                {
                    if (i < collection.Elements.Count)
                    {
                        var complexValue = collection.Elements[i] as QueryStructuralValue;
                        this.CompareValues(complexValue, complexInstanceNamedValues, propertyPath + "." + i);
                    }

                    i++;
                    complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                }

                this.WriteErrorIfNotEqual(propertyPath, collection.Elements.Count, i, "The number of expected items '{0}' does not match the actual '{1}' for propertyPath {2}", collection.Elements.Count, i, propertyPath);
            }
        }
Пример #12
0
        private void SynchronizeNavigationProperty(QueryEntityType entitySetBaseType, QueryStructuralValue entity, SerializableNamedValue namedValue, IDictionary <EntityDataKey, QueryStructuralValue> existingEntityGraph)
        {
            var reference = namedValue.Value as SerializableEntity;

            if (reference != null)
            {
                QueryStructuralValue synchronized;
                if (reference.EntitySetName == entitySetBaseType.EntitySet.Name)
                {
                    // for self references, we don't need to rebuild the set of existing entities
                    synchronized = this.FindAndSynchronizeEntity(entitySetBaseType, reference, existingEntityGraph);
                }
                else
                {
                    synchronized = this.FindAndSynchronizeEntity(reference);
                }

                entity.SetValue(namedValue.Name, synchronized);
                return;
            }

            var collection = namedValue.Value as IEnumerable <SerializableEntity>;

            if (collection != null)
            {
                var oldCollection = entity.GetCollectionValue(namedValue.Name);

                // clear out the old collection, if it exists
                if (entity.MemberNames.Contains(namedValue.Name))
                {
                    oldCollection.Elements.Clear();
                }
                else
                {
                    // by default we set IsSorted to true, enabling ordering verification.
                    oldCollection = QueryCollectionValue.Create(oldCollection.Type.ElementType, new QueryValue[0], true);
                }

                entity.SetValue(namedValue.Name, oldCollection);

                // go through the new elements, synchronize them, and add them
                foreach (var related in collection)
                {
                    QueryStructuralValue synchronized;
                    if (related.EntitySetName == entitySetBaseType.EntitySet.Name)
                    {
                        // for self references, we don't need to rebuild the set of existing entities
                        synchronized = this.FindAndSynchronizeEntity(entitySetBaseType, related, existingEntityGraph);
                    }
                    else
                    {
                        synchronized = this.FindAndSynchronizeEntity(related);
                    }

                    oldCollection.Elements.Add(synchronized);
                }

                return;
            }

            ExceptionUtilities.Assert(namedValue.Value == null, "Value of navigation property '{0}' was not a reference, a collection of references, or null. Value was '{1}'", namedValue.Name, namedValue.Value);
            entity.SetValue(namedValue.Name, entity.Type.Properties.Single(p => p.Name == namedValue.Name).PropertyType.NullValue);
        }
        private QueryStructuralValue CloneStructuralValue(Dictionary<QueryStructuralValue, QueryStructuralValue> identityMap, QueryStructuralValue qsv)
        {
            if (qsv.IsNull)
            {
                return qsv;
            }

            QueryStructuralValue clonedValue;

            if (identityMap.TryGetValue(qsv, out clonedValue))
            {
                return clonedValue;
            }

            clonedValue = qsv.Type.CreateNewInstance();
            identityMap.Add(qsv, clonedValue);
      
            foreach (var m in qsv.Type.Properties)
            {
                // copy scalar properties
                if (m.PropertyType is QueryScalarType)
                {
                    clonedValue.SetValue(m.Name, qsv.GetScalarValue(m.Name));
                    continue;
                }

                // copy stream properties
                if (m.PropertyType is AstoriaQueryStreamType)
                {
                    if (m.Name.Contains("DefaultStream"))
                    {
                        clonedValue.SetDefaultStreamValue(qsv.GetDefaultStreamValue());
                    }
                    else
                    {
                        clonedValue.SetStreamValue(m.Name, qsv.GetStreamValue(m.Name));
                    }

                    continue;
                }

                var qst = m.PropertyType as QueryStructuralType;
                if (m.PropertyType is QueryStructuralType)
                {
                    if (!qst.IsValueType)
                    {
                        // skip reference types, clone everything else
                        continue;
                    }

                    clonedValue.SetValue(m.Name, this.CloneStructuralValue(identityMap, qsv.GetStructuralValue(m.Name)));
                }

                var qct = m.PropertyType as QueryCollectionType;
                if (qct != null)
                {
                    var elementStructuralType = qct.ElementType as QueryStructuralType;
                    if (elementStructuralType != null)
                    {
                        if (!elementStructuralType.IsValueType)
                        {
                            // skip collections of reference types, clone everything else
                            continue;
                        }
                    }

                    clonedValue.SetValue(m.Name, this.CloneCollectionValue(identityMap, qsv.GetCollectionValue(m.Name)));
                }
            }

            return clonedValue;
        }
        private void SetCollectionProperty(QueryStructuralValue instance, QueryProperty memberProperty, List<QueryValue> collectionElements)
        {
            QueryCollectionValue queryCollectionValue = instance.GetCollectionValue(memberProperty.Name);

            queryCollectionValue.Elements.Clear();
            foreach (QueryValue queryValue in collectionElements)
            {
                queryCollectionValue.Elements.Add(queryValue);
            }

            instance.SetValue(memberProperty.Name, queryCollectionValue);
        }