/// <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()));
            }
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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());
        }
示例#5
0
        /// <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()));
        }
示例#6
0
 /// <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");
 }
示例#7
0
 /// <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);
            }
        }