/// <summary> /// Create a new ParameterQueryToken given the parent and visitor if any /// </summary> /// <param name="parent">The parent of the Any/All query.</param> /// <param name="visitor">The name of the visitor for the Any/All query.</param> public ParameterQueryToken(NavigationPropertyToken parent, string visitor) { ExceptionUtils.CheckArgumentNotNull(visitor, "visitor"); this.parent = parent; this.visitor = visitor; }
/// <summary> /// Create a new ParameterQueryToken given the parent and visitor if any /// </summary> /// <param name="parent">The parent of the Any/All query.</param> /// <param name="visitor">The name of the visitor for the Any/All query.</param> public ParameterQueryToken(NavigationPropertyToken parent, string visitor) { ExceptionUtils.CheckArgumentNotNull(visitor, "visitor"); this.parent = parent; this.visitor = visitor; }
/// <summary> /// Write the navigation property token as URI part to this builder. /// </summary> /// <param name="navigation">To write as URI part.</param> protected virtual void WriteNavigationProperty(NavigationPropertyToken navigation) { ExceptionUtils.CheckArgumentNotNull(navigation, "navigation"); if (navigation.Parent != null) { this.WriteQuery(navigation.Parent); this.builder.Append(ExpressionConstants.SymbolForwardSlash); } this.builder.Append(navigation.Name); }
/// <summary> /// Parses the All portion of the query /// </summary> /// <param name="parent">The parent of the All node.</param> /// <returns>The lexical token representing the All query.</returns> private QueryToken ParseAll(QueryToken parent) { NavigationPropertyToken parentNav = (NavigationPropertyToken)parent; parentNav.AnyAllParent = true; this.lexer.NextToken(); if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.OpenParen) { throw ParseError(Strings.UriQueryExpressionParser_OpenParenExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText)); } this.lexer.NextToken(); // When faced with All(), return the same thing as if you encountered All(a : true) if (this.lexer.CurrentToken.Kind == ExpressionTokenKind.CloseParen) { this.lexer.NextToken(); return(new AllQueryToken(new LiteralQueryToken(true, "True"), "a", parent)); } ParameterQueryToken paramToken = new ParameterQueryToken(parentNav, this.lexer.CurrentToken.GetIdentifier()); this.parameters.Add(this.lexer.CurrentToken.GetIdentifier(), paramToken); string tmp = this.lexer.CurrentToken.GetIdentifier(); this.lexer.NextToken(); this.lexer.NextToken(); QueryToken expr = this.ParseExpression(); if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen) { throw ParseError(Strings.UriQueryExpressionParser_CloseParenOrCommaExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText)); } this.lexer.NextToken(); return(new AllQueryToken(expr, tmp, parent)); }
/// <summary> /// Binds a <see cref="NavigationPropertyToken"/>. /// </summary> /// <param name="segmentToken">The segment token to bind.</param> /// <returns>The bound node.</returns> private SingleValueQueryNode BindNavigationProperty(NavigationPropertyToken segmentToken) { QueryNode source = null; IEdmNavigationProperty property; if (segmentToken.Parent != null) { source = this.Bind(segmentToken.Parent); IEdmType entityType = null; if (IsDerivedComplexType(segmentToken, GetType(source))) { IEdmProperty returnProperty = BindProperty(GetType(source).ToTypeReference(), segmentToken.Name); return new PropertyAccessQueryNode() { Source = (SingleValueQueryNode)source, Property = returnProperty }; } else { entityType = GetType(source); } ParameterQueryNode parentNode = new ParameterQueryNode { ParameterType = entityType.ToTypeReference() }; property = (IEdmNavigationProperty)BindProperty(parentNode.TypeReference, segmentToken.Name); } else { if (IsDerivedComplexType(segmentToken, this.parameter.TypeReference.Definition)) { IEdmProperty returnProperty = BindProperty(new EdmEntityTypeReference((IEdmEntityType)this.parameter.TypeReference.Definition, true), segmentToken.Name); return new PropertyAccessQueryNode { Source = this.parameter, Property = returnProperty }; } property = (IEdmNavigationProperty)BindProperty(this.parameter.TypeReference, segmentToken.Name); } // Ensure that only collections head Any queries and nothing else if (property.OwnMultiplicity() == EdmMultiplicity.Many && segmentToken.AnyAllParent == false) { throw new ODataException(Strings.MetadataBinder_PropertyAccessSourceNotSingleValue(segmentToken.Name)); } else if (property.OwnMultiplicity() != EdmMultiplicity.Many && segmentToken.AnyAllParent == true) { throw new ODataException(Strings.MetadataBinder_InvalidAnyAllHead); } return new NavigationPropertyNode() { Source = source, NavigationProperty = property }; }
/// <summary> /// Determines if a segment is a complex type. /// </summary> /// <param name="instance">Segment to be checked.</param> /// <param name="parentType">The type of the parent segment.</param> /// <returns>True if segment represents a complex type and false otherwise.</returns> private static Boolean IsDerivedComplexType(NavigationPropertyToken instance, IEdmType parentType) { IEdmProperty property = BindProperty(parentType.ToTypeReference(), instance.Name); return property.Type.IsODataComplexTypeKind(); }
/// <summary> /// Write the navigation property token as URI part to this builder. /// </summary> /// <param name="navigation">To write as URI part.</param> protected virtual void WriteNavigationProperty(NavigationPropertyToken navigation) { ExceptionUtils.CheckArgumentNotNull(navigation, "navigation"); if (navigation.Parent != null) { this.WriteQuery(navigation.Parent); this.builder.Append(ExpressionConstants.SymbolForwardSlash); } this.builder.Append(navigation.Name); }