Beispiel #1
0
        /// <summary>
        /// Fixes up the properties of the structural value based on the given selected paths
        /// </summary>
        /// <param name="instance">The value to fix up</param>
        /// <param name="selectedPaths">The selected paths for the value's scope</param>
        /// <returns>The fixed-up value</returns>
        private QueryStructuralValue FixupPropertiesForSelect(QueryStructuralValue instance, IEnumerable <string> selectedPaths)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");
            ExceptionUtilities.CheckCollectionNotEmpty(selectedPaths, "selectedPaths");

            var entityType = instance.Type as QueryEntityType;

            ExceptionUtilities.CheckObjectNotNull(entityType, "Select is not supported on non-entity types");

            var masked = MaskedQueryStructuralValue.Create(instance);

            bool wildCard = selectedPaths.Contains(Endpoints.SelectAll);

            var propertyNames = entityType.EntityType.AllProperties.Select(p => p.Name).Concat(entityType.Properties.Streams().Select(m => m.Name));

            foreach (string propertyName in propertyNames)
            {
                if (!selectedPaths.Contains(Uri.EscapeDataString(propertyName)) && !wildCard)
                {
                    // Primitive, bag and stream properties are either entirely present or entirely missing.
                    // However, complex properties can be partially present if a mapped sub-property has a
                    // null value. For this reason, we recursively hide the property and all sub-properties.
                    HidePropertyRecursive(masked, propertyName);
                }
            }

            foreach (string propertyName in entityType.EntityType.AllNavigationProperties.Select(p => p.Name))
            {
                string pathMarker = Uri.EscapeDataString(propertyName) + "/";
                var    subpaths   = selectedPaths.Where(p => p.StartsWith(pathMarker, StringComparison.Ordinal)).Select(p => p.Substring(pathMarker.Length));

                var value = instance.GetValue(propertyName);
                ExceptionUtilities.CheckObjectNotNull(value, "Value for property '{0}' was null", propertyName);

                if (selectedPaths.Contains(Uri.EscapeDataString(propertyName)))
                {
                    continue;
                }
                else if (subpaths.Any())
                {
                    var maskedValue = this.VisitEntityValues(value, s => this.FixupPropertiesForSelect(s, subpaths));
                    masked.SetValue(propertyName, maskedValue);
                }
                else if (wildCard)
                {
                    masked.SetValue(propertyName, value.Type.NullValue);
                }
                else
                {
                    masked.HideMember(propertyName);
                }
            }

            return(masked);
        }
Beispiel #2
0
        /// <summary>
        /// Fixes up the properties of the structural value based on the given expanded paths
        /// </summary>
        /// <param name="instance">The value to fix up</param>
        /// <param name="expandedPaths">The expanded paths for the value's scope</param>
        /// <returns>The fixed-up value</returns>
        private QueryStructuralValue FixupPropertiesForExpand(QueryStructuralValue instance, IEnumerable <string> expandedPaths)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");
            ExceptionUtilities.CheckArgumentNotNull(expandedPaths, "expandedPaths");

            var entityType = instance.Type as QueryEntityType;

            ExceptionUtilities.CheckObjectNotNull(entityType, "Expand is not supported on non-entity types");

            var masked = MaskedQueryStructuralValue.Create(instance);

            foreach (var navigation in entityType.EntityType.AllNavigationProperties)
            {
                string expandedPath;
                string propertyName = navigation.Name;
                var    value        = instance.GetValue(propertyName);

                ExceptionUtilities.CheckObjectNotNull(value, "Value for property '{0}' was null", propertyName);

                bool   match      = TryGetExpandedPath(expandedPaths, propertyName, entityType.EntityType, out expandedPath);
                string pathMarker = expandedPath + "/";
                var    subpaths   = expandedPaths.Where(p => p.StartsWith(pathMarker, StringComparison.Ordinal)).Select(p => p.Substring(pathMarker.Length));

                // note that if there is match, we still need to fix up up any children, even if there are no subpaths
                if (subpaths.Any() || match)
                {
                    // recurse
                    var maskedValue = this.VisitEntityValues(value, s => this.FixupPropertiesForExpand(s, subpaths));

                    // handle page limit on expanded collections
                    if (maskedValue.Type is QueryCollectionType)
                    {
                        var collection = maskedValue as QueryCollectionValue;
                        ExceptionUtilities.CheckObjectNotNull(collection, "Value was a collection type, but not a collection value");

                        var relatedSet         = entityType.EntitySet.GetRelatedEntitySet(navigation);
                        var relatedSetPageSize = relatedSet.GetEffectivePageSize();
                        if (relatedSetPageSize.HasValue && this.applyPagingInExpands)
                        {
                            collection  = this.AddOrderingForPagingToQueryCollectionValue(collection);
                            maskedValue = collection.Take(relatedSetPageSize.Value);
                        }
                    }

                    masked.SetValue(propertyName, maskedValue);
                }
                else if (!match)
                {
                    // set any non-expanded navigation properties to null
                    masked.SetValue(propertyName, value.Type.NullValue);
                }
            }

            return(masked);
        }
Beispiel #3
0
        /// <summary>
        /// Compares structural object with the expected value.
        /// </summary>
        /// <param name="expected">Expected value.</param>
        /// <param name="actual">Actual value.</param>
        /// <param name="path">The path to the compared object (for debugging purposes).</param>
        /// <param name="shouldThrow">Should exception be thrown if error is encountered.</param>
        /// <returns>
        /// Result of the comparison, Success, Failure or Skipped.
        /// </returns>
        protected override ComparisonResult CompareStructural(QueryStructuralValue expected, object actual, string path, bool shouldThrow)
        {
            var hasDefaultStreamProperty = expected.Type.Properties.Any(p => p.Name == AstoriaQueryStreamType.DefaultStreamPropertyName);

            if (hasDefaultStreamProperty)
            {
                MaskedQueryStructuralValue newExpected = MaskedQueryStructuralValue.Create(expected);

                // need to remove the default stream property from the list of MemberNames for the expected value since the actual won't have that
                newExpected.HideMember(AstoriaQueryStreamType.DefaultStreamPropertyName);

                return(base.CompareStructural(newExpected, actual, path, shouldThrow));
            }
            else
            {
                return(base.CompareStructural(expected, actual, path, shouldThrow));
            }
        }
Beispiel #4
0
        /// <summary>
        /// Recursively hides the properties, and any child properties.
        /// </summary>
        /// <param name="maskedQueryValue">The query value with properties to hide.</param>
        /// <param name="propertyName">The name of the property to hide.</param>
        private static void HidePropertyRecursive(MaskedQueryStructuralValue maskedQueryValue, string propertyName)
        {
            var propertyValue = maskedQueryValue.GetValue(propertyName) as QueryStructuralValue;

            if (propertyValue != null)
            {
                var maskedPropertyValue = propertyValue as MaskedQueryStructuralValue;
                if (maskedPropertyValue == null)
                {
                    maskedPropertyValue = MaskedQueryStructuralValue.Create(propertyValue);
                }

                var subPropertyNames = maskedPropertyValue.AllMemberNames.ToList();
                foreach (string subPropertyName in subPropertyNames)
                {
                    HidePropertyRecursive(maskedPropertyValue, subPropertyName);
                }

                maskedQueryValue.SetValue(propertyName, maskedPropertyValue);
            }

            maskedQueryValue.HideMember(propertyName);
        }