예제 #1
0
        private QueryCollectionValue RewriteGroupingElements(QueryCollectionValue groupings, LinqLambdaExpression elementSelectorLambda)
        {
            var groupingElementType   = (QueryGroupingType)groupings.Type.ElementType;
            var rewrittenGroupingType = new QueryGroupingType(groupingElementType.Key.PropertyType, elementSelectorLambda.Body.ExpressionType, groupingElementType.EvaluationStrategy);

            var rewrittenGroupings = new List <QueryValue>();

            foreach (var grouping in groupings.Elements.Cast <QueryStructuralValue>())
            {
                QueryCollectionValue elements = grouping.GetCollectionValue("Elements");
                var rewrittenElements         = elements.Select(e => this.EvaluateLambda <QueryValue>(elementSelectorLambda, e));
                var rewrittenGrouping         = rewrittenGroupingType.CreateNewInstance();
                rewrittenGrouping.SetValue("Key", grouping.GetValue("Key"));
                rewrittenGrouping.SetValue("Elements", rewrittenElements);
                rewrittenGroupings.Add(rewrittenGrouping);
            }

            var result = rewrittenGroupingType.CreateCollectionType().CreateCollectionWithValues(rewrittenGroupings);

            return(result);
        }
예제 #2
0
        /// <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()));
            }
        }