Exemplo n.º 1
0
        /// Wraps the SELECT part of a query using a format string provided in the argument.
        ///
        /// If a subquery parts aggregator is open, redirects the call to it instead.
        public void SetSelectPartAsScalar(string scalarPartFormat)
        {
            if (_visitingSubQueryExpression)
            {
                _subQueryExpressionPartsAggregator.SetSelectPartAsScalar(scalarPartFormat);
            }
            else
            {
                var renamingPartIndex = SelectPart.IndexOf("\" AS \"", StringComparison.Ordinal) + 1;
                SelectPart = renamingPartIndex > 0 ? SelectPart.Substring(0, renamingPartIndex) : SelectPart;

                SelectPart = string.Format(scalarPartFormat, SelectPart);
            }
        }
        public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index)
        {
            var operatorType = resultOperator.GetType();

            if (AggretatingOperators.ContainsKey(operatorType))
            {
                _queryParts.SetSelectPartAsScalar(AggretatingOperators[operatorType]);
                base.VisitResultOperator(resultOperator, queryModel, index);
            }

            else if (SetOperators.ContainsKey(operatorType))
            {
                dynamic subQueryResultOperator = Convert.ChangeType(resultOperator, operatorType);
                this.VisitSubQueryExpression(subQueryResultOperator.Source2); // Source2 is a SubQueryExpression.
                _queryParts.AddSubQueryLinkAction(SetOperators[operatorType]);
                base.VisitResultOperator(resultOperator, queryModel, index);
            }

            else if (resultOperator is TakeResultOperator || resultOperator is SkipResultOperator)
            {
                var limitter        = resultOperator is TakeResultOperator ? "LIMIT" : "OFFSET";
                var constExpression = resultOperator is TakeResultOperator ?
                                      (resultOperator as TakeResultOperator).Count :
                                      (resultOperator as SkipResultOperator).Count;

                _queryParts.AddPagingPart(limitter, GetPsqlExpression(constExpression));
                base.VisitResultOperator(resultOperator, queryModel, index);
            }

            else if (resultOperator is AnyResultOperator)
            {
                _queryParts.AddSubQueryLinkAction("EXISTS ({0})");
            }

            else if (resultOperator is AllResultOperator)
            {
                var subQuery = (resultOperator as AllResultOperator);
                _queryParts.AddWherePart($"NOT ({GetPsqlExpression(subQuery.Predicate)})");
                _queryParts.AddSubQueryLinkAction("NOT EXISTS ({0})");
            }

            else
            {
                throw new NotImplementedException(
                          $"This LINQ provider does not provide the {resultOperator} result operator.");
            }
        }