private void ExpandItem() { if (_parser.CurrentTokenKind == QueryExpressionTokenKind.Identifier) { var member = _parser.BindMember((string)_parser.TokenData); if (!(member is PropertyInfo property) || !IsNavigationProperty(property, out var itemType, out var isCollection)) { _parser.ReportError($"Property '{_parser.TokenData}' is no navigation property"); return; } if (_clauses.ContainsKey(property)) { _parser.ReportError($"Property '{_parser.TokenData}' is already expanded."); return; } var clause = new ExpandClause(itemType, property, isCollection); _clauses[property] = clause; _parser.NextToken(); if (_parser.CurrentTokenKind == QueryExpressionTokenKind.OpenParenthesis) { _parser.NextToken(); ExpandItemOptions(clause); } } }
private void OrderByItemList() { while (true) { var expression = _parser.CommonExpr(); var direction = OrderByDirection.Acending; if (_parser.CurrentTokenKind == QueryExpressionTokenKind.Keyword) { var order = (string)_parser.TokenData; switch (order) { case "asc": direction = OrderByDirection.Acending; _parser.NextToken(); break; case "desc": direction = OrderByDirection.Descending; _parser.NextToken(); break; default: _parser.ReportError( $"Invalid token '{order}' after sort expression, expecting 'asc' or 'desc'"); return; } } var item = new OrderByClause(expression, direction); _clauses.Add(item); if (_parser.CurrentTokenKind == QueryExpressionTokenKind.Comma) { _parser.NextToken(); } else { break; } } }
private void SelectItem(SelectClause currentClause) { switch (_parser.CurrentTokenKind) { case QueryExpressionTokenKind.Star: _parser.NextToken(); currentClause.IsStarSelect = true; break; case QueryExpressionTokenKind.Identifier: { var member = _parser.BindMember((string)_parser.TokenData) as PropertyInfo; if (member == null) { _parser.ReportError($"'{_parser.TokenData}' is not a valid property for selection"); return; } _parser.NextToken(); // not yet selected -> create subclause if (!currentClause.SelectClauses.TryGetValue(member, out var subClause)) { subClause = new SelectClause(); subClause.SelectedMember = member; currentClause.SelectClauses[member] = subClause; } // nested expression if (_parser.CurrentTokenKind == QueryExpressionTokenKind.Slash) { _parser.NextToken(); // activate sub clauses subClause.SelectClauses = new Dictionary <PropertyInfo, SelectClause>(); // parse next segment into this subclause if (IsNavigationProperty(member, out var expressionType, out _)) { _parser.PushThis(Expression.Parameter(expressionType)); SelectItem(subClause); _parser.PopThis(); } else if (member.DeclaringType != null) { _parser.ReportError($"'{member.DeclaringType.FullName}.{member.Name}' is no navigation property, cannot expand with slash"); } else { _parser.ReportError($"'{member.Name}' is no navigation property, cannot expand with slash"); } } else { // $select=complexProperty/subproperty is equal to $select=complexProperty/subproperty/* subClause.IsStarSelect = true; } break; }