/// <summary>Marks the entire subtree as projected.</summary> /// <remarks>This is used when there were no projections specified in the query /// to mark the entire tree as projected.</remarks> internal void MarkSubtreeAsProjected() { this.projectSubtree = true; this.projectAllImmediateProperties = false; foreach (ProjectionNode node in this.nodes) { ExpandedProjectionNode expandedNode = node as ExpandedProjectionNode; if (expandedNode != null) { expandedNode.MarkSubtreeAsProjected(); } } }
/// <summary> /// Applies projections from the given select/expand clause to the tree represented by the given node. /// </summary> /// <param name="currentNode">The expand tree to apply projections to.</param> private void ApplyProjectionsToExpandTree(ExpandedProjectionNode currentNode) { // If this is the last segment in the path and it was a navigation property, // mark it to include the entire subtree if (currentNode.SelectExpandClause.AllSelected) { currentNode.ProjectionFound = true; currentNode.MarkSubtreeAsProjected(); } foreach (var selectItem in currentNode.SelectExpandClause.SelectedItems) { currentNode.ProjectionFound = true; // '*' is special, it means "Project all immediate properties on this level." if (selectItem is WildcardSelectItem) { currentNode.ProjectAllImmediateProperties = true; continue; } if (selectItem is NamespaceQualifiedWildcardSelectItem) { currentNode.ProjectAllImmediateOperations = true; continue; } ODataPath path; var expandItem = selectItem as ExpandedNavigationSelectItem; if (expandItem != null) { path = expandItem.PathToNavigationProperty; } else { var pathSelectionItem = selectItem as PathSelectItem; Debug.Assert(pathSelectionItem != null, "Unexpeced selection item type: " + selectItem.GetType()); path = pathSelectionItem.SelectedPath; } ExpandedProjectionNode childNode = this.ApplyPathSelection(path, currentNode); if (expandItem != null) { if (childNode == null) { throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_ProjectedPropertyWithoutMatchingExpand(((NavigationPropertySegment)path.LastSegment).NavigationProperty.Name)); } this.ApplyProjectionsToExpandTree(childNode); } } }