/// <summary> /// Resolves types for the specified expression. /// </summary> /// <param name="expression">The expression to resolve types for.</param> /// <returns>Expression with resolved types.</returns> public QueryExpression Visit(LinqGroupByExpression expression) { var source = this.ResolveTypes(expression.Source); var sourceType = ValidateSourceIsACollection(source); var keySelector = this.ResolveLambdaTypes(expression.KeySelector, sourceType); var elementSelector = expression.ElementSelector != null?this.ResolveLambdaTypes(expression.ElementSelector, sourceType) : null; var keyCollectionType = keySelector.Body.ExpressionType.CreateCollectionType(); var elementCollectionType = expression.ElementSelector != null?elementSelector.Body.ExpressionType.CreateCollectionType() : sourceType; if (expression.ResultSelector != null) { // resolve lambda strips the collection out of parameters, but the second parameter to the result is a collection // so we pass collection of collections var resultSelector = this.ResolveLambdaTypes(expression.ResultSelector, keyCollectionType, elementCollectionType.CreateCollectionType()); var resultType = resultSelector.Body.ExpressionType; return(new LinqGroupByExpression(source, keySelector, elementSelector, resultSelector, resultType.CreateCollectionType())); } else { var groupingType = new QueryGroupingType(keySelector.Body.ExpressionType, elementCollectionType.ElementType, this.EvaluationStrategy); return(new LinqGroupByExpression(source, keySelector, elementSelector, null, groupingType.CreateCollectionType())); } }
/// <summary> /// Replaces the given expression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Replaced expression.</returns> public virtual QueryExpression Visit(LinqGroupByExpression expression) { QueryExpression source = this.ReplaceExpression(expression.Source); var keySelector = (LinqLambdaExpression)this.ReplaceExpression(expression.KeySelector); var elementSelector = expression.ElementSelector != null ? (LinqLambdaExpression)this.ReplaceExpression(expression.ElementSelector) : null; var resultSelector = expression.ResultSelector != null ? (LinqLambdaExpression)this.ReplaceExpression(expression.ResultSelector) : null; if (HasChanged(expression.Source, source) || HasChanged(expression.KeySelector, keySelector) || HasChanged(expression.ElementSelector, elementSelector) || HasChanged(expression.ResultSelector, resultSelector)) { return(new LinqGroupByExpression(source, keySelector, elementSelector, resultSelector, expression.ExpressionType)); } return(expression); }
/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <returns>Value of the expression.</returns> public QueryValue Visit(LinqGroupByExpression expression) { var source = this.EvaluateCollection(expression.Source); Func <QueryCollectionValue, Func <QueryValue, QueryValue>, QueryValue> keySelectorEvaluator = (collection, keySelector) => collection.GroupBy(keySelector); var result = (QueryCollectionValue)keySelectorEvaluator(source, v => this.EvaluateLambda <QueryScalarValue>(expression.KeySelector, v)); if (expression.ElementSelector != null) { result = this.RewriteGroupingElements(result, expression.ElementSelector); } if (expression.ResultSelector != null) { var rewrittenResultElements = result.Elements.Cast <QueryStructuralValue>().Select(e => this.EvaluateLambda <QueryValue>(expression.ResultSelector, e.GetValue("Key"), e.GetValue("Elements"))); result = expression.ResultSelector.Body.ExpressionType.CreateCollectionType().CreateCollectionWithValues(rewrittenResultElements); } return(result); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqGroupByExpression expression) { CodeExpression source = this.GenerateCode(expression.Source); var keySelector = (CodeLambdaExpression)this.GenerateCode(expression.KeySelector); var arguments = new List<CodeLambdaExpression>(new[] { keySelector }); if (expression.ElementSelector != null) { var elementSelector = (CodeLambdaExpression)this.GenerateCode(expression.ElementSelector); arguments.Add(elementSelector); } if (expression.ResultSelector != null) { var resultSelector = (CodeLambdaExpression)this.GenerateCode(expression.ResultSelector); arguments.Add(resultSelector); } return source.Call("GroupBy", arguments.ToArray()); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqGroupByExpression expression) { CodeExpression source = this.GenerateCode(expression.Source); var keySelector = (CodeLambdaExpression)this.GenerateCode(expression.KeySelector); var arguments = new List <CodeLambdaExpression>(new[] { keySelector }); if (expression.ElementSelector != null) { var elementSelector = (CodeLambdaExpression)this.GenerateCode(expression.ElementSelector); arguments.Add(elementSelector); } if (expression.ResultSelector != null) { var resultSelector = (CodeLambdaExpression)this.GenerateCode(expression.ResultSelector); arguments.Add(resultSelector); } return(source.Call("GroupBy", arguments.ToArray())); }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqGroupByExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public virtual string Visit(LinqGroupByExpression expression) { throw new TaupoNotSupportedException("Not supported"); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public abstract CodeExpression Visit(LinqGroupByExpression expression);
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqGroupByExpression expression) { var source = this.GenerateCode(expression.Source); var codeQuerySource = source as CodeQueryExpression; string inputParameterName = this.GetInputParameterName(codeQuerySource); string groupParameterName = this.GetGroupParameterName(codeQuerySource); var prm = expression.KeySelector.Parameters.Single(); var newPrm = new CodeParameterDeclarationExpression(new CodeImplicitTypeReference(), inputParameterName); this.ParameterNamesDictionary.Add(prm, newPrm); CodeLambdaExpression lambda; try { lambda = (CodeLambdaExpression)this.GenerateCode(expression.KeySelector); } finally { this.ParameterNamesDictionary.Remove(prm); } if (codeQuerySource != null) { if (codeQuerySource.GroupByKeySelector == null && codeQuerySource.Select == null) { return(new CodeQueryExpression( inputParameterName, groupParameterName, codeQuerySource.From, codeQuerySource.Where, codeQuerySource.OrderByKeySelectors, codeQuerySource.AreDescending, lambda.Body, codeQuerySource.Select)); } else { return(new CodeQueryExpression( inputParameterName, groupParameterName, codeQuerySource, null, Enumerable.Empty <CodeExpression>(), Enumerable.Empty <bool>(), lambda.Body, null)); } } else { return(new CodeQueryExpression( inputParameterName, groupParameterName, source, null, Enumerable.Empty <CodeExpression>(), Enumerable.Empty <bool>(), lambda.Body, null)); } }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqGroupByExpression expression) { var source = this.GenerateCode(expression.Source); var codeQuerySource = source as CodeQueryExpression; string inputParameterName = this.GetInputParameterName(codeQuerySource); string groupParameterName = this.GetGroupParameterName(codeQuerySource); var prm = expression.KeySelector.Parameters.Single(); var newPrm = new CodeParameterDeclarationExpression(new CodeImplicitTypeReference(), inputParameterName); this.ParameterNamesDictionary.Add(prm, newPrm); CodeLambdaExpression lambda; try { lambda = (CodeLambdaExpression)this.GenerateCode(expression.KeySelector); } finally { this.ParameterNamesDictionary.Remove(prm); } if (codeQuerySource != null) { if (codeQuerySource.GroupByKeySelector == null && codeQuerySource.Select == null) { return new CodeQueryExpression( inputParameterName, groupParameterName, codeQuerySource.From, codeQuerySource.Where, codeQuerySource.OrderByKeySelectors, codeQuerySource.AreDescending, lambda.Body, codeQuerySource.Select); } else { return new CodeQueryExpression( inputParameterName, groupParameterName, codeQuerySource, null, Enumerable.Empty<CodeExpression>(), Enumerable.Empty<bool>(), lambda.Body, null); } } else { return new CodeQueryExpression( inputParameterName, groupParameterName, source, null, Enumerable.Empty<CodeExpression>(), Enumerable.Empty<bool>(), lambda.Body, null); } }