protected override SelectQueryPart Parse(string parameterValue) { var matches = Regex.Matches(parameterValue, @"(?:\w+/)*\w+", RegexOptions.IgnoreCase).Cast <Match>(); var selectors = new List <MemberAccessFilterExpression>(); foreach (var match in matches) { var s = match.Value.Split('/'); var selector = s .Aggregate <string, MemberAccessFilterExpression>(null, FilterExpression.MemberAccess); selectors.Add(selector); } return(ODataQueryPart.Select(selectors.ToArray())); }
public override void VisitSelectClause(SelectClause selectClause, QueryModel queryModel) { var selectors = new List <string>(); if (selectClause.Selector.NodeType == ExpressionType.MemberAccess) { // TODO: handle access of child properties in selector statements var selector = (MemberExpression)selectClause.Selector; selectors.Add(selector.Member.Name); } else if (selectClause.Selector.NodeType == ExpressionType.New) { // TODO: trying to support this may not be viable... var constructor = (NewExpression)selectClause.Selector; foreach (var argument in constructor.Arguments) { if (argument.NodeType == ExpressionType.MemberAccess) { var member = (MemberExpression)argument; selectors.Add(member.Member.Name); } else { throw new NotSupportedException("Cannot select non-members from the result set."); } } } else if (selectClause.Selector.NodeType == ExpressionType.MemberInit) { var memberInit = (MemberInitExpression)selectClause.Selector; var constructor = memberInit.NewExpression; foreach (var argument in constructor.Arguments) { if (argument.NodeType == ExpressionType.MemberAccess) { var member = (MemberExpression)argument; selectors.Add(member.Member.Name); } else { throw new NotSupportedException("Cannot select non-members from the result set."); } } foreach (var memberBinding in memberInit.Bindings) { if (memberBinding.BindingType == MemberBindingType.Assignment) { var assignment = (MemberAssignment)memberBinding; if (assignment.Expression.NodeType == ExpressionType.MemberAccess) { var selectedMember = (MemberExpression)assignment.Expression; if (memberBinding.Member.Name == selectedMember.Member.Name) { selectors.Add(selectedMember.Member.Name); } else { throw new NotSupportedException($"Cannot alias member '{selectedMember.Member.Name}' as '{memberBinding.Member.Name}'. Aliasing projections is not supported in LinqToRest."); } } else { throw new NotSupportedException("Cannot select non-members into the result set."); } } else { throw new NotSupportedException("Cannot select lists from the result set."); } } } if (selectors.Any()) { _query.SelectPredicate = ODataQueryPart.Select(selectors.Distinct().Select(FilterExpression.MemberAccess).ToArray()); } base.VisitSelectClause(selectClause, queryModel); }