public static void ReWrite(QueryModel queryModel, ISessionFactory sessionFactory) { var nsqmv = new NestedSelectDetector(sessionFactory); nsqmv.VisitExpression(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, "Key"); var expressions = new List <ExpressionHolder>(); var identifier = GetIdentifier(sessionFactory, new QuerySourceReferenceExpression(queryModel.MainFromClause)); var rewriter = new SelectClauseRewriter(key, expressions, identifier, replacements); var resultSelector = rewriter.VisitExpression(queryModel.SelectClause.Selector); elementExpression.AddRange(expressions); var keySelector = CreateSelector(elementExpression, 0); var elementSelector = CreateSelector(elementExpression, 1); var groupBy = EnumerableHelper.GetMethod("GroupBy", new[] { typeof(IEnumerable <>), typeof(Func <,>), typeof(Func <,>) }, new[] { typeof(object[]), typeof(Tuple), typeof(Tuple) }); var input = Expression.Parameter(typeof(IEnumerable <object>), "input"); var lambda = Expression.Lambda( Expression.Call(groupBy, 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); }
public static void ReWrite(QueryModel queryModel, ISessionFactory sessionFactory) { var nsqmv = new NestedSelectDetector(sessionFactory); nsqmv.VisitExpression(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, "Key"); var expressions = new List<ExpressionHolder>(); var identifier = GetIdentifier(sessionFactory, new QuerySourceReferenceExpression(queryModel.MainFromClause)); var rewriter = new SelectClauseRewriter(key, expressions, identifier, replacements); var resultSelector = rewriter.VisitExpression(queryModel.SelectClause.Selector); elementExpression.AddRange(expressions); var keySelector = CreateSelector(elementExpression, 0); var elementSelector = CreateSelector(elementExpression, 1); var groupBy = EnumerableHelper.GetMethod("GroupBy", new[] { typeof (IEnumerable<>), typeof (Func<,>), typeof (Func<,>) }, new[] { typeof (object[]), typeof (Tuple), typeof (Tuple) }); var input = Expression.Parameter(typeof (IEnumerable<object>), "input"); var lambda = Expression.Lambda( Expression.Call(groupBy, 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); }
public static void ReWrite(QueryModel queryModel, ISessionFactory sessionFactory) { var nsqmv = new NestedSelectDetector(); nsqmv.VisitExpression(queryModel.SelectClause.Selector); if (!nsqmv.HasSubquery) return; var subQueryModel = nsqmv.Expression.QueryModel; var mainFromClause = subQueryModel.MainFromClause; var restrictions = subQueryModel.BodyClauses .OfType<WhereClause>() .Select(w => new NhWithClause(w.Predicate)); var join = new NhJoinClause(mainFromClause.ItemName, mainFromClause.ItemType, mainFromClause.FromExpression, restrictions); queryModel.BodyClauses.Add(join); var visitor = new SwapQuerySourceVisitor(subQueryModel.MainFromClause, join); queryModel.TransformExpressions(visitor.Swap); var ctor = Tuple.Type.GetConstructor(System.Type.EmptyTypes); var key = Expression.Parameter(Tuple.Type, "key"); var values = Expression.Parameter(typeof (IEnumerable<Tuple>), "values"); var expressions = new List<ExpressionHolder>(); var rewriter = new SelectClauseRewriter(key, values, expressions); var resultSelector = rewriter.VisitExpression(queryModel.SelectClause.Selector); var field = Tuple.Type.GetField("Items"); var keySelector = CreateSelector(ctor, field, expressions, 0); var elementSelector = CreateSelector(ctor, field, expressions, 1); var cast = EnumerableHelper.GetMethod("Cast", new[] {typeof (IEnumerable)}, new[] {typeof (object[])}); var groupBy = EnumerableHelper.GetMethod("GroupBy", new[] {typeof (IEnumerable<>), typeof (Func<,>), typeof (Func<,>), typeof (Func<,,>)}, new[] {typeof (object[]), Tuple.Type, Tuple.Type, queryModel.SelectClause.Selector.Type}); var toList = EnumerableHelper.GetMethod("ToList", new[] { typeof(IEnumerable<>) }, new[] { queryModel.SelectClause.Selector.Type }); var input = Expression.Parameter(typeof (IEnumerable<object>), "input"); var call = Expression.Call(toList, Expression.Call(groupBy, Expression.Call(cast, input), keySelector, elementSelector, Expression.Lambda(resultSelector, key, values))); var lambda = Expression.Lambda(call, input); queryModel.ResultOperators.Add(new ClientSideSelect2(lambda)); var initializers = expressions.Select(e => e.Expression == null ? GetIdentifier(sessionFactory, expressions, e) : ConvertToObject(e.Expression)); queryModel.SelectClause.Selector = Expression.NewArrayInit(typeof (object), initializers); }
public static void ReWrite(QueryModel queryModel, ISessionFactory sessionFactory) { var nsqmv = new NestedSelectDetector(); nsqmv.VisitExpression(queryModel.SelectClause.Selector); if (!nsqmv.HasSubquery) { return; } var subQueryModel = nsqmv.Expression.QueryModel; var mainFromClause = subQueryModel.MainFromClause; var restrictions = subQueryModel.BodyClauses .OfType <WhereClause>() .Select(w => new NhWithClause(w.Predicate)); var join = new NhJoinClause(mainFromClause.ItemName, mainFromClause.ItemType, mainFromClause.FromExpression, restrictions); queryModel.BodyClauses.Add(join); var visitor = new SwapQuerySourceVisitor(subQueryModel.MainFromClause, join); queryModel.TransformExpressions(visitor.Swap); var ctor = Tuple.Type.GetConstructor(System.Type.EmptyTypes); var key = Expression.Parameter(Tuple.Type, "key"); var values = Expression.Parameter(typeof(IEnumerable <Tuple>), "values"); var expressions = new List <ExpressionHolder>(); var rewriter = new SelectClauseRewriter(key, values, expressions); var resultSelector = rewriter.VisitExpression(queryModel.SelectClause.Selector); var field = Tuple.Type.GetField("Items"); var keySelector = CreateSelector(ctor, field, expressions, 0); var elementSelector = CreateSelector(ctor, field, expressions, 1); var cast = EnumerableHelper.GetMethod("Cast", new[] { typeof(IEnumerable) }, new[] { typeof(object[]) }); var groupBy = EnumerableHelper.GetMethod("GroupBy", new[] { typeof(IEnumerable <>), typeof(Func <,>), typeof(Func <,>), typeof(Func <, ,>) }, new[] { typeof(object[]), Tuple.Type, Tuple.Type, queryModel.SelectClause.Selector.Type }); var toList = EnumerableHelper.GetMethod("ToList", new[] { typeof(IEnumerable <>) }, new[] { queryModel.SelectClause.Selector.Type }); var input = Expression.Parameter(typeof(IEnumerable <object>), "input"); var call = Expression.Call(toList, Expression.Call(groupBy, Expression.Call(cast, input), keySelector, elementSelector, Expression.Lambda(resultSelector, key, values))); var lambda = Expression.Lambda(call, input); queryModel.ResultOperators.Add(new ClientSideSelect2(lambda)); var initializers = expressions.Select(e => e.Expression == null ? GetIdentifier(sessionFactory, expressions, e) : ConvertToObject(e.Expression)); queryModel.SelectClause.Selector = Expression.NewArrayInit(typeof(object), initializers); }