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)); }
private void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel) { // Move the result operator up if (queryModel.ResultOperators.Count != 0) { throw new NotImplementedException(); } var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0]; queryModel.ResultOperators.Add(groupBy); foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses) { queryModel.BodyClauses.Add(bodyClause); } // Replace the outer select clause... queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel)); // Point all query source references to the outer from clause queryModel.TransformExpressions(s => new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap(s)); // Replace the outer query source queryModel.MainFromClause = subQueryExpression.QueryModel.MainFromClause; }
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause, QueryModel queryModel, int destinationIndex) { if (!CheckFlattenable(subQueryExpression.QueryModel)) return; var mainFromClause = subQueryExpression.QueryModel.MainFromClause; CopyFromClauseData(mainFromClause, fromClause); var innerSelectorMapping = new QuerySourceMapping(); innerSelectorMapping.AddMapping(fromClause, subQueryExpression.QueryModel.SelectClause.Selector); queryModel.TransformExpressions((ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerSelectorMapping, false))); InsertBodyClauses(subQueryExpression.QueryModel.BodyClauses, queryModel, destinationIndex); CopyResultOperators(subQueryExpression.QueryModel.ResultOperators, queryModel); var innerBodyClauseMapping = new QuerySourceMapping(); innerBodyClauseMapping.AddMapping(mainFromClause, new QuerySourceReferenceExpression(fromClause)); queryModel.TransformExpressions((ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerBodyClauseMapping, false))); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual ISet<IQuerySource> FindQuerySourcesRequiringMaterialization([NotNull] QueryModel queryModel) { _queryModel = queryModel; _selector = queryModel.SelectClause.Selector; _queryModel.TransformExpressions(Visit); var querySources = new HashSet<IQuerySource>( _querySources.Where(kv => kv.Value > 0).Select(kv => kv.Key)); return querySources; }
private void ReWrite(QueryModel queryModel) { VisitQueryModel(queryModel); if (_joins.Count > 0) { MemberExpressionSwapper swap = new MemberExpressionSwapper(_expressionMap); queryModel.TransformExpressions(swap.VisitExpression); foreach (var join in _joins.Values) { queryModel.BodyClauses.Add(join); } } }
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel) { // Move the result operator up if (queryModel.ResultOperators.Count != 0) { throw new NotImplementedException(); } var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0]; queryModel.ResultOperators.Add(groupBy); for (int i = 0; i < queryModel.BodyClauses.Count; i++) { var clause = queryModel.BodyClauses[i]; clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel)); //all outer where clauses actually are having clauses var whereClause = clause as WhereClause; if (whereClause != null) { queryModel.BodyClauses.RemoveAt(i); queryModel.BodyClauses.Insert(i, new NhHavingClause(whereClause.Predicate)); } } foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses) { queryModel.BodyClauses.Add(bodyClause); } // Replace the outer select clause... queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel)); // Point all query source references to the outer from clause queryModel.TransformExpressions(s => new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap(s)); // Replace the outer query source queryModel.MainFromClause = subQueryExpression.QueryModel.MainFromClause; }
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel) { // we can not flattern subquery if outer query has body clauses. var subQueryModel = subQueryExpression.QueryModel; var subQueryMainFromClause = subQueryModel.MainFromClause; if (queryModel.BodyClauses.Count == 0) { foreach (var resultOperator in subQueryModel.ResultOperators) queryModel.ResultOperators.Add(resultOperator); foreach (var bodyClause in subQueryModel.BodyClauses) queryModel.BodyClauses.Add(bodyClause); } else { var cro = new ContainsResultOperator(new QuerySourceReferenceExpression(subQueryMainFromClause)); var newSubQueryModel = subQueryModel.Clone(); newSubQueryModel.ResultOperators.Add(cro); newSubQueryModel.ResultTypeOverride = typeof (bool); var where = new WhereClause(new SubQueryExpression(newSubQueryModel)); queryModel.BodyClauses.Add(where); if (!queryModel.BodyClauses.OfType<OrderByClause>().Any()) { var orderByClauses = subQueryModel.BodyClauses.OfType<OrderByClause>(); foreach (var orderByClause in orderByClauses) queryModel.BodyClauses.Add(orderByClause); } } var visitor1 = new PagingRewriterSelectClauseVisitor(); queryModel.SelectClause.TransformExpressions(visitor1.Swap); // Point all query source references to the outer from clause var visitor2 = new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryMainFromClause); queryModel.TransformExpressions(visitor2.Swap); // Replace the outer query source queryModel.MainFromClause = subQueryMainFromClause; }
public static void ReWrite(QueryModel model) { var visitor = new QueryReferenceExpressionFlattener(model); model.TransformExpressions(visitor.VisitExpression); }
private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy) { foreach (var resultOperator in queryModel.ResultOperators.Where(resultOperator => !AcceptableOuterResultOperators.Contains(resultOperator.GetType()))) { throw new NotImplementedException("Cannot use group by with the " + resultOperator.GetType().Name + " result operator."); } // Move the result operator up. SubQueryFromClauseFlattener.InsertResultOperators(subQueryModel.ResultOperators, queryModel); for (var i = 0; i < queryModel.BodyClauses.Count; i++) { var clause = queryModel.BodyClauses[i]; clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel)); //all outer where clauses actually are having clauses var whereClause = clause as WhereClause; if (whereClause != null) { queryModel.BodyClauses.RemoveAt(i); queryModel.BodyClauses.Insert(i, new NhHavingClause(whereClause.Predicate)); } } foreach (var bodyClause in subQueryModel.BodyClauses) queryModel.BodyClauses.Add(bodyClause); // Replace the outer select clause... queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel)); // Point all query source references to the outer from clause var visitor = new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryModel.MainFromClause); queryModel.TransformExpressions(visitor.Swap); // Replace the outer query source queryModel.MainFromClause = subQueryModel.MainFromClause; }
public static void ReWrite(QueryModel model) { var visitor = new ArrayIndexExpressionFlattener(); model.TransformExpressions(visitor.VisitExpression); }
/// <inheritdoc /> public override void VisitQueryModel(QueryModel queryModel) { queryModel.TransformExpressions(e => new MixinExpressionVisitor(Model).Visit(e)); base.VisitQueryModel(queryModel); }
public bool RequiresBuffering(QueryModel queryModel) { queryModel.TransformExpressions(Visit); return _requiresBuffering; }
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); }
public bool AnyShadowAccess(QueryModel queryModel) { queryModel.TransformExpressions(Visit); return _anyShadowAccess; }
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); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> protected override Expression VisitSubQuery(SubQueryExpression expression) { var oldParentSelector = _selector; var oldQueryModel = _queryModel; _selector = expression.QueryModel.SelectClause.Selector; _queryModel = expression.QueryModel; _queryModel.TransformExpressions(Visit); _selector = oldParentSelector; _queryModel = oldQueryModel; var querySourceReferenceExpression = expression.QueryModel.SelectClause.Selector as QuerySourceReferenceExpression; if (querySourceReferenceExpression != null) { var querySourceTracingExpressionVisitor = new QuerySourceTracingExpressionVisitor(); if (expression.QueryModel.ResultOperators.LastOrDefault() is DefaultIfEmptyResultOperator) { var underlyingQuerySource = (((querySourceReferenceExpression.ReferencedQuerySource as MainFromClause) ?.FromExpression as QuerySourceReferenceExpression) ?.ReferencedQuerySource as GroupJoinClause)?.JoinClause; if (underlyingQuerySource != null) { AddQuerySource(underlyingQuerySource); } } var resultQuerySource = querySourceTracingExpressionVisitor .FindResultQuerySourceReferenceExpression( _selector, querySourceReferenceExpression.ReferencedQuerySource); if ((resultQuerySource == null) && !(expression.QueryModel.ResultOperators.LastOrDefault() is OfTypeResultOperator)) { _querySources[querySourceReferenceExpression.ReferencedQuerySource]--; } foreach (var sourceExpression in _queryModel.ResultOperators.Select(SetResultOperationSourceExpression).Where(e => e != null)) { if (sourceExpression.Equals(expression)) { var parentQuerySource = _selector as QuerySourceReferenceExpression; if ((parentQuerySource != null) && (_querySources[parentQuerySource.ReferencedQuerySource] > 0) && (parentQuerySource.Type == querySourceReferenceExpression.Type)) { _querySources[querySourceReferenceExpression.ReferencedQuerySource]++; } } } } return expression; }