private void FlattenSubQuery(SubQueryExpression subQueryExpression, MainFromClause fromClause,
                                     QueryModel queryModel)
        {
            // Create a new client-side select for the outer
            // TODO - don't like calling GetGenericArguments here...
            var clientSideSelect = new ClientSideSelect(new NonAggregatingGroupBySelectRewriter().Visit(queryModel.SelectClause.Selector, subQueryExpression.Type.GetGenericArguments()[0], queryModel.MainFromClause));

            // Replace the outer select clause...
            queryModel.SelectClause = subQueryExpression.QueryModel.SelectClause;

            MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;

            CopyFromClauseData(innerMainFromClause, fromClause);

            // Move the result operator up 
            if (queryModel.ResultOperators.Count != 0)
            {
                throw new NotImplementedException();
            }

            queryModel.ResultOperators.Add(new NonAggregatingGroupBy((GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0]));
            queryModel.ResultOperators.Add(clientSideSelect);
        }
예제 #2
0
        private void ProcessClientSideSelect(ClientSideSelect resultOperator)
        {
            var inputType = resultOperator.SelectClause.Parameters[0].Type;
            var outputType = resultOperator.SelectClause.Type.GetGenericArguments()[1];

            var inputList = Expression.Parameter(typeof (IEnumerable<>).MakeGenericType(inputType), "inputList");

            var selectMethod = EnumerableHelper.GetMethod("Select", new[] { typeof(IEnumerable<>), typeof(Func<,>) }, new[] { inputType, outputType });
            var toListMethod = EnumerableHelper.GetMethod("ToList", new[] {typeof (IEnumerable<>)}, new[] {outputType});

            var lambda = Expression.Lambda(
                            Expression.Call(toListMethod,
                                Expression.Call(selectMethod, inputList, resultOperator.SelectClause)), 
                            inputList);

            _listTransformers.Add(lambda);
        }