Exemplo n.º 1
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            var name = node.Method.Name;
            LambdaExpression lambdaExpression;

            switch (name)
            {
            case "Where":
                lambdaExpression = GetLambdaExpression(node);
                var whereTranslator = new WhereQueryTranslator();
                WhereClause = whereTranslator.Translate(lambdaExpression);
                Visit(node.Arguments[0]);
                break;

            case "FirstOrDefault":
                FirstOrDefaultClause = "TOP 1 *";
                Visit(node.Arguments[0]);
                break;

            case "ThenBy":
            case "OrderBy":
            case "OrderByDescending":
            case "ThenByDescending":
                var sortingType = name.Contains("Descending") ? SortingType.DESC : SortingType.ASC;
                lambdaExpression = GetLambdaExpression(node);
                var orderByTranslator = new OrderByQueryTranslator(sortingType);
                orderByClauses_.Add(orderByTranslator.Translate(lambdaExpression));
                Visit(node.Arguments[0]);
                break;

            case "Select":
                lambdaExpression = GetLambdaExpression(node);
                var selectTranslator = new SelectQueryTranslator();
                SelectClause = selectTranslator.Translate(lambdaExpression);
                Visit(node.Arguments[0]);
                break;

            default:
                break;
            }

            return(node);
        }
Exemplo n.º 2
0
        private void VisitOrderByStatements(List <MethodCallExpression> callChain, Type typeResult)
        {
            string[] names = new[] { nameof(q.OrderBy), nameof(q.ThenBy), nameof(q.OrderByDescending), nameof(q.ThenByDescending) };

            List <MethodCallExpression> tmp = callChain.Where(p => names.Contains(p.Method.Name)).ToList();

            OrderByQueryTranslator s = new OrderByQueryTranslator(typeResult);

            foreach (MethodCallExpression item in tmp)
            {
                s.Accept(item);
                callChain.Remove(item);
            }

            if (!string.IsNullOrEmpty(s.Statement))
            {
                OrderByPart = $" ORDER BY {s.Statement}";
            }
        }
        public override string TranslateToSql(Expression expr)
        {
            var externalPredicates = new List <Expression <Func <ShadowRow, bool> > >();

            var itIsCount = false;
            var itIsFirst = false;
            var skipUsed  = ExpressionsInternalToolkit.SkipIsUsed(expr);
            var takeUsed  = ExpressionsInternalToolkit.TakeIsUsed(expr);

#pragma warning disable CS0642

            if (itIsCount = ExpressionsInternalToolkit.IsCountQueryableCall(expr))
            {
                ;
            }
            else if (itIsFirst = ExpressionsInternalToolkit.IsFirstQueryableCall(expr) ||
                                 ExpressionsInternalToolkit.IsFirstOrDefaultQueryableCall(expr))
            {
                ;
            }
#pragma warning restore CS0642


            var selectOnlyTranslator = new SelectOnlyTranslator();

            if (itIsCount)
            {
                _sb.Append("SELECT COUNT (");
                _sb.Append(selectOnlyTranslator.TranslateToSql(expr));
                _sb.Append(") FROM ");
                var mCall = expr as MethodCallExpression;
                if (mCall.Arguments.Count == 2)
                {
                    var lambda      = ExpressionsInternalToolkit.SkipUnary(mCall.Arguments[1]) as LambdaExpression; // skip Quote
                    var lambdaTyped =
                        Expression.Lambda <Func <ShadowRow, bool> >(lambda.Body, ExpressionBuilders.DefaultRowParameter);
                    externalPredicates.Add(lambdaTyped);
                }
            }
            else if (itIsFirst && !skipUsed)
            {
                _sb.Append("SELECT TOP 1 ");
                _sb.Append(selectOnlyTranslator.TranslateToSql(expr));
                _sb.Append(" FROM ");
                var mCall = expr as MethodCallExpression;
                if (mCall.Arguments.Count == 2)
                {
                    var lambda      = ExpressionsInternalToolkit.SkipUnary(mCall.Arguments[1]) as LambdaExpression; // skip Quote
                    var lambdaTyped =
                        Expression.Lambda <Func <ShadowRow, bool> >(lambda.Body, ExpressionBuilders.DefaultRowParameter);
                    externalPredicates.Add(lambdaTyped);
                }
            }
            else
            {
                _sb.Append("SELECT ");
                _sb.Append(selectOnlyTranslator.TranslateToSql(expr));
                _sb.Append(" FROM ");
            }

            _sb.Append(_sourceName);

            var whereLine = new WhereQueryTranslator(_queryParamsStore,
                                                     externalPredicates.Any() ? externalPredicates.ToArray() : null)
                            .TranslateToSql(expr);
            if (!string.IsNullOrWhiteSpace(whereLine))
            {
                _sb.Append(" WHERE ");
                _sb.Append(whereLine);
            }

            if (!itIsCount)
            {
                var orderByLine = new OrderByQueryTranslator(_queryParamsStore)
                                  .TranslateToSql(expr);
                var orderByUsed = !string.IsNullOrWhiteSpace(orderByLine);
                if (orderByUsed)
                {
                    _sb.Append(" ORDER BY ");
                    _sb.Append(orderByLine);
                }

                if (skipUsed)
                {
                    if (!orderByUsed)
                    {
                        _sb.Append(" ORDER BY (SELECT NULL)");
                    }

                    _sb.Append(" OFFSET ");
                    var skipCount = ExpressionsInternalToolkit.GetSkipCount(expr);
                    _sb.Append(_queryParamsStore.Append(skipCount));
                    _sb.Append(" ROWS");
                }

                if (takeUsed)
                {
                    if (!skipUsed)
                    {
                        if (!orderByUsed)
                        {
                            _sb.Append(" ORDER BY (SELECT NULL)");
                        }

                        _sb.Append(" OFFSET 0 ROWS");
                    }

                    _sb.Append(" FETCH NEXT ");
                    var takeCount = ExpressionsInternalToolkit.GetTakeCount(expr);
                    _sb.Append(_queryParamsStore.Append(takeCount));
                    _sb.Append(" ROW ONLY");
                }
            }

            if (itIsFirst && skipUsed)
            {
                _sb.Append(" FETCH NEXT 1 ROW ONLY");
            }

            return(_sb.ToString());
        }