public virtual void AddQuery([NotNull] IQuerySource querySource, [NotNull] SelectExpression selectExpression) { Check.NotNull(querySource, nameof(querySource)); Check.NotNull(selectExpression, nameof(selectExpression)); QueriesBySource.Add(querySource, selectExpression); }
public virtual SelectExpression TryGetQuery([NotNull] IQuerySource querySource) { Check.NotNull(querySource, nameof(querySource)); SelectExpression selectExpression; return(QueriesBySource.TryGetValue(querySource, out selectExpression) ? selectExpression : QueriesBySource.Values.SingleOrDefault(se => se.HandlesQuerySource(querySource))); }
/// <summary> /// Get active ReadOnlyExpression /// </summary> /// <param name="querySource"></param> /// <returns></returns> public virtual ReadOnlyExpression TryGetQuery([NotNull] IQuerySource querySource) { Check.NotNull(querySource, nameof(querySource)); return(QueriesBySource.TryGetValue(querySource, out ReadOnlyExpression roe) ? roe : QueriesBySource .Values .LastOrDefault(e => e.HandlesQuerySource(querySource))); }
/// <summary> /// Add read only expression /// </summary> /// <param name="querySource"></param> /// <param name="readOnlyExpression"></param> public virtual void AddQuery( [NotNull] IQuerySource querySource, [NotNull] ReadOnlyExpression readOnlyExpression ) { Check.NotNull(querySource, nameof(querySource)); Check.NotNull(readOnlyExpression, nameof(readOnlyExpression)); QueriesBySource.Add(querySource, readOnlyExpression); }
public override SelectExpression TryGetQuery(IQuerySource querySource) { SelectExpression selectExpression; if (QueriesBySource.TryGetValue(querySource, out selectExpression)) { return(selectExpression); } return(QueriesBySource.Values.SingleOrDefault(se => se.HandlesQuerySource(querySource))); }
public override void VisitQueryModel(QueryModel queryModel) { base.VisitQueryModel(queryModel); if (ContextOptions.FindExtension <SqlServerOptionsExtension>()?.RowNumberPaging == true) { var visitor = new RowNumberPagingExpressionVisitor(); SelectExpression mainSelectExpression; if (QueriesBySource.TryGetValue(queryModel.MainFromClause, out mainSelectExpression)) { visitor.Visit(mainSelectExpression); } foreach (var additionalSource in queryModel.BodyClauses.OfType <IQuerySource>()) { SelectExpression additionalFromExpression; if (QueriesBySource.TryGetValue(additionalSource, out additionalFromExpression)) { visitor.Visit(mainSelectExpression); } } } }
protected virtual void OptimizeJoinClause( [NotNull] JoinClause joinClause, [NotNull] QueryModel queryModel, int index, [NotNull] Action baseVisitAction, [NotNull] MethodInfo operatorToFlatten, bool outerJoin = false) { Check.NotNull(joinClause, nameof(joinClause)); Check.NotNull(queryModel, nameof(queryModel)); Check.NotNull(baseVisitAction, nameof(baseVisitAction)); Check.NotNull(operatorToFlatten, nameof(operatorToFlatten)); RequiresClientJoin = true; var previousQuerySource = FindPreviousQuerySource(queryModel, index); var previousSelectExpression = previousQuerySource != null ? TryGetQuery(previousQuerySource) : null; var previousSelectProjectionCount = previousSelectExpression?.Projection.Count ?? -1; baseVisitAction(); if (previousSelectExpression != null) { var selectExpression = TryGetQuery(joinClause); if (selectExpression != null) { var sqlTranslatingExpressionVisitor = _sqlTranslatingExpressionVisitorFactory.Create(this); var predicate = sqlTranslatingExpressionVisitor .Visit( Expression.Equal( joinClause.OuterKeySelector, joinClause.InnerKeySelector)); if (predicate != null) { QueriesBySource.Remove(joinClause); previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount); var tableExpression = selectExpression.Tables.Single(); var projection = QueryCompilationContext .QuerySourceRequiresMaterialization(joinClause) ? selectExpression.Projection : Enumerable.Empty <Expression>(); var joinExpression = !outerJoin ? previousSelectExpression.AddInnerJoin(tableExpression, projection) : previousSelectExpression.AddOuterJoin(tableExpression, projection); joinExpression.Predicate = predicate; if (outerJoin) { var outerJoinOrderingExtractor = new OuterJoinOrderingExtractor(); outerJoinOrderingExtractor.Visit(predicate); foreach (var expression in outerJoinOrderingExtractor.Expressions) { previousSelectExpression .AddToOrderBy(new Ordering(expression, OrderingDirection.Asc)); } } Expression = _queryFlattenerFactory .Create( joinClause, QueryCompilationContext, operatorToFlatten, previousSelectProjectionCount) .Flatten((MethodCallExpression)Expression); RequiresClientJoin = false; } } } if (RequiresClientJoin) { CheckClientEval(joinClause); } }
public override void VisitAdditionalFromClause( AdditionalFromClause fromClause, QueryModel queryModel, int index) { Check.NotNull(fromClause, nameof(fromClause)); Check.NotNull(queryModel, nameof(queryModel)); base.VisitAdditionalFromClause(fromClause, queryModel, index); RequiresClientSelectMany = true; var selectExpression = TryGetQuery(fromClause); if (selectExpression != null && selectExpression.Tables.Count == 1) { var previousQuerySource = FindPreviousQuerySource(queryModel, index); if (previousQuerySource != null && !RequiresClientJoin) { var previousSelectExpression = TryGetQuery(previousQuerySource); if (previousSelectExpression != null) { if (!QueryCompilationContext.QuerySourceRequiresMaterialization(previousQuerySource)) { previousSelectExpression.ClearProjection(); previousSelectExpression.IsProjectStar = false; } var readerOffset = previousSelectExpression.Projection.Count; var correlated = selectExpression.IsCorrelated(); if (correlated) { if (!QueryCompilationContext.IsLateralJoinSupported) { return; } previousSelectExpression .AddLateralJoin(selectExpression.Tables.First(), selectExpression.Projection); } else { previousSelectExpression .AddCrossJoin(selectExpression.Tables.First(), selectExpression.Projection); } QueriesBySource.Remove(fromClause); Expression = _queryFlattenerFactory .Create( fromClause, QueryCompilationContext, LinqOperatorProvider.SelectMany, readerOffset) .Flatten((MethodCallExpression)Expression); RequiresClientSelectMany = false; } } } if (RequiresClientSelectMany) { CheckClientEval(fromClause); } }