public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { var subQuery = fromClause.FromExpression as SubQueryExpression; if (subQuery == null) return; var subQueryModel = subQuery.QueryModel; if (!IsLeftJoin(subQueryModel)) return; 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); var innerSelectorMapping = new QuerySourceMapping(); innerSelectorMapping.AddMapping(fromClause, subQueryModel.SelectClause.Selector); queryModel.TransformExpressions(ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerSelectorMapping, false)); queryModel.BodyClauses.RemoveAt(index); queryModel.BodyClauses.Insert(index, @join); InsertBodyClauses(subQueryModel.BodyClauses.Where(b => !(b is WhereClause)), queryModel, index + 1); var innerBodyClauseMapping = new QuerySourceMapping(); innerBodyClauseMapping.AddMapping(mainFromClause, new QuerySourceReferenceExpression(@join)); queryModel.TransformExpressions(ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerBodyClauseMapping, false)); }
public override AdditionalFromClause Clone(CloneContext cloneContext) { var joinClause = new NhJoinClause(ItemName, ItemType, FromExpression); foreach (var withClause in Restrictions) { var withClause2 = new NhWithClause(withClause.Predicate); joinClause.Restrictions.Add(withClause2); } cloneContext.QuerySourceMapping.AddMapping(this, new QuerySourceReferenceExpression(joinClause)); return base.Clone(cloneContext); }
public Expression AddJoin(Expression expression, string key) { NhJoinClause join; if (!_joins.TryGetValue(key, out join)) { join = new NhJoinClause(_nameGenerator.GetNewName(), expression.Type, expression); _queryModel.BodyClauses.Add(join); _joins.Add(key, join); } return new QuerySourceReferenceExpression(@join); }
private static Expression ProcessSubquery(ISessionFactory sessionFactory, ICollection <ExpressionHolder> elementExpression, QueryModel queryModel, Expression @group, QueryModel subQueryModel) { var resultTypeOverride = subQueryModel.ResultTypeOverride; if (resultTypeOverride != null && !resultTypeOverride.IsArray && !resultTypeOverride.IsEnumerableOfT()) { return(null); } var subQueryMainFromClause = subQueryModel.MainFromClause; var restrictions = subQueryModel.BodyClauses .OfType <WhereClause>() .Select(w => new NhWithClause(w.Predicate)); var join = new NhJoinClause(subQueryMainFromClause.ItemName, subQueryMainFromClause.ItemType, subQueryMainFromClause.FromExpression, restrictions); queryModel.BodyClauses.Add(@join); var visitor = new SwapQuerySourceVisitor(subQueryMainFromClause, @join); queryModel.TransformExpressions(visitor.Swap); var selector = subQueryModel.SelectClause.Selector; var collectionType = subQueryModel.GetResultType(); var elementType = selector.Type; var source = new QuerySourceReferenceExpression(@join); return(BuildSubCollectionQuery(sessionFactory, elementExpression, @group, source, selector, elementType, collectionType)); }
private void VisitNhJoinClause(string querySourceName, NhJoinClause joinClause) { var expression = HqlGeneratorExpressionTreeVisitor.Visit(joinClause.FromExpression, VisitorParameters).AsExpression(); var alias = _hqlTree.TreeBuilder.Alias(querySourceName); HqlTreeNode hqlJoin; if (joinClause.IsInner) { hqlJoin = _hqlTree.TreeBuilder.Join(expression, @alias); } else { hqlJoin = _hqlTree.TreeBuilder.LeftJoin(expression, @alias); } foreach (var withClause in joinClause.Restrictions) { var booleanExpression = HqlGeneratorExpressionTreeVisitor.Visit(withClause.Predicate, VisitorParameters).AsBooleanExpression(); hqlJoin.AddChild(_hqlTree.TreeBuilder.With(booleanExpression)); } _hqlTree.AddFromClause(hqlJoin); }
private static Expression ProcessSubquery(ISessionFactory sessionFactory, ICollection<ExpressionHolder> elementExpression, QueryModel queryModel, Expression @group, QueryModel subQueryModel) { var subQueryMainFromClause = subQueryModel.MainFromClause; var restrictions = subQueryModel.BodyClauses .OfType<WhereClause>() .Select(w => new NhWithClause(w.Predicate)); var join = new NhJoinClause(subQueryMainFromClause.ItemName, subQueryMainFromClause.ItemType, subQueryMainFromClause.FromExpression, restrictions); queryModel.BodyClauses.Add(@join); var visitor = new SwapQuerySourceVisitor(subQueryMainFromClause, @join); queryModel.TransformExpressions(visitor.Swap); var selector = subQueryModel.SelectClause.Selector; var collectionType = subQueryModel.GetResultType(); var elementType = selector.Type; var source = new QuerySourceReferenceExpression(@join); return BuildSubCollectionQuery(sessionFactory, elementExpression, @group, source, selector, elementType, collectionType); }
private static Expression ProcessMemberExpression(ISessionFactory sessionFactory, ICollection<ExpressionHolder> elementExpression, QueryModel queryModel, Expression @group, Expression memberExpression) { var join = new NhJoinClause(new NameGenerator(queryModel).GetNewName(), GetElementType(memberExpression.Type), memberExpression); queryModel.BodyClauses.Add(@join); var source = new QuerySourceReferenceExpression(@join); return BuildSubCollectionQuery(sessionFactory, elementExpression, @group, source, source, source.Type, memberExpression.Type); }
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 override void VisitNhJoinClause(NhJoinClause joinClause, QueryModel queryModel, int index) { _namer.Add(joinClause); }
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 virtual void VisitNhJoinClause(NhJoinClause joinClause, QueryModel queryModel, int index) { }