public static void ReWrite(QueryModel queryModel, ISessionFactory sessionFactory) { var nsqmv = new NestedSelectDetector(sessionFactory); nsqmv.Visit(queryModel.SelectClause.Selector); if (!nsqmv.HasSubqueries) { return; } var elementExpression = new List <ExpressionHolder>(); var group = Expression.Parameter(typeof(IGrouping <Tuple, Tuple>), "g"); var replacements = new Dictionary <Expression, Expression>(); foreach (var expression in nsqmv.Expressions) { var processed = ProcessExpression(queryModel, sessionFactory, expression, elementExpression, group); if (processed != null) { replacements.Add(expression, processed); } } var key = Expression.Property(group, IGroupingKeyProperty); var expressions = new List <ExpressionHolder>(); var identifier = GetIdentifier(sessionFactory, new QuerySourceReferenceExpression(queryModel.MainFromClause)); var rewriter = new SelectClauseRewriter(key, expressions, identifier, replacements); var resultSelector = rewriter.Visit(queryModel.SelectClause.Selector); elementExpression.AddRange(expressions); var keySelector = CreateSelector(elementExpression, 0); var elementSelector = CreateSelector(elementExpression, 1); var input = Expression.Parameter(typeof(IEnumerable <object>), "input"); var lambda = Expression.Lambda( Expression.Call(GroupByMethod, Expression.Call(CastMethod, input), keySelector, elementSelector), input); queryModel.ResultOperators.Add(new ClientSideSelect2(lambda)); queryModel.ResultOperators.Add(new ClientSideSelect(Expression.Lambda(resultSelector, @group))); var initializers = elementExpression.Select(e => ConvertToObject(e.Expression)); queryModel.SelectClause.Selector = Expression.NewArrayInit(typeof(object), initializers); }
private static LambdaExpression MakeSelector(ICollection <ExpressionHolder> elementExpression, Expression @select, Expression identifier) { var parameter = Expression.Parameter(typeof(Tuple), "value"); var rewriter = new SelectClauseRewriter(parameter, elementExpression, identifier, 1, new Dictionary <Expression, Expression>()); var selectorBody = rewriter.Visit(@select); return(Expression.Lambda(selectorBody, parameter)); }