private KeyValuePair <string, Expression> ParseSelectPart(Type thisType, NodeBase node, ParameterExpression thisParam, string parsedString) { string propertyName = null; if (node.NodeType == NodeType.As) { var asNode = (BinaryOperatorNode)node; if (asNode.Right.NodeType != NodeType.Symbol) { throw QueryParseException.Create(node.ParserNode, "Need to specify a property name on left side of as in select expression.", parsedString, null, QueryParseErrorReason.GenericError); } propertyName = ((SymbolNode)asNode.Right).Name; node = asNode.Left; } else { if (!TryGetImplicitPropertyName(node, out propertyName)) { throw QueryParseException.Create(node.ParserNode, $"Unable to infer property name of select expression ({node})", parsedString, null, QueryParseErrorReason.GenericError); } } var exprParser = new NodeTreeToExpressionConverter(this.queryPropertyResolver, parsedString); var lambdaExpression = exprParser.ToLambdaExpression(thisParam, thisParam.WrapAsEnumerable(), Enumerable.Empty <ParameterExpression>(), node); return(new KeyValuePair <string, Expression>(propertyName, lambdaExpression.Body)); }
private Expression ParseLambda(LambdaNode lambdaNode, Type expectedType) { if (expectedType.UniqueToken() == typeof(Expression <>).UniqueToken()) { // Quote if expression return(Expression.Quote(ParseLambda(lambdaNode, expectedType.GetGenericArguments()[0]))); } var nestedConverter = new NodeTreeToExpressionConverter(this.propertyResolver, this.parsedString); // TODO: Check that we don't already have a arg with same name. // TODO: Proper check that we have a func here if (expectedType.UniqueToken() != typeof(Func <,>).UniqueToken()) { throw CreateParseException(lambdaNode, "Can't parse lambda to expected type that is not a Func delegate.."); } if (expectedType.GetGenericArguments()[0].IsGenericParameter) { throw CreateParseException(lambdaNode, "Unable to resolve generic type for parsing lambda."); } var funcTypeArgs = expectedType.GetGenericArguments(); // TODO: Support multiple lambda args..(?) var lambdaParams = lambdaNode.Argument .WrapAsEnumerable() .Select((x, idx) => Expression.Parameter(funcTypeArgs[idx], x.Name)) .ToList(); return(nestedConverter.ToLambdaExpression(this.thisParam, lambdaParams, this.parameters.Values, lambdaNode.Body)); }
private LambdaExpression TransformTreeNodeToExpression(Type thisType, string odataExpression, NodeBase tempTree) { var nodeTreeToExpressionConverter = new NodeTreeToExpressionConverter(this.queryPropertyResolver, odataExpression); var lambdaExpression = nodeTreeToExpressionConverter.ToLambdaExpression(thisType, tempTree); return(lambdaExpression); }