Esempio n. 1
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            if (sequence.SelectQuery.Select.TakeValue != null ||
                sequence.SelectQuery.Select.SkipValue != null ||
                sequence.SelectQuery.Select.IsDistinct && !builder.DataContextInfo.SqlProviderFlags.IsDistinctOrderBySupported)
            {
                sequence = new SubQueryContext(sequence);
            }

            var lambda  = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            var sparent = sequence.Parent;
            var order   = new ExpressionContext(buildInfo.Parent, sequence, lambda);
            var body    = lambda.Body.Unwrap();
            var sql     = builder.ConvertExpressions(order, body, ConvertFlags.Key);

            builder.ReplaceParent(order, sparent);

            if (!methodCall.Method.Name.StartsWith("Then"))
            {
                sequence.SelectQuery.OrderBy.Items.Clear();
            }

            foreach (var expr in sql)
            {
                var e = builder.ConvertSearchCondition(sequence, expr.Sql);
                sequence.SelectQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending"));
            }

            return(sequence);
        }
Esempio n. 2
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            var wrapped = false;

            if (sequence.SelectQuery.Select.TakeValue != null ||
                sequence.SelectQuery.Select.SkipValue != null)
            {
                sequence = new SubQueryContext(sequence);
                wrapped  = true;
            }

            var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap();

            SqlInfo[] sql;

            while (true)
            {
                var sparent = sequence.Parent;
                var order   = new ExpressionContext(buildInfo.Parent, sequence, lambda);
                var body    = lambda.Body.Unwrap();
                sql = builder.ConvertExpressions(order, body, ConvertFlags.Key, null);

                builder.ReplaceParent(order, sparent);

                if (wrapped)
                {
                    break;
                }

                // handle situation when order by uses complex field

                var isComplex = false;

                foreach (var sqlInfo in sql)
                {
                    // immutable expressions will be removed later
                    //
                    var isImmutable = QueryHelper.IsConstant(sqlInfo.Sql);
                    if (isImmutable)
                    {
                        continue;
                    }

                    // possible we have to extend this list
                    //
                    isComplex = null != new QueryVisitor().Find(sqlInfo.Sql,
                                                                e => e.ElementType == QueryElementType.SqlQuery);
                    if (isComplex)
                    {
                        break;
                    }
                }

                if (!isComplex)
                {
                    break;
                }

                sequence = new SubQueryContext(sequence);
                wrapped  = true;
            }


            if (!methodCall.Method.Name.StartsWith("Then") && !Configuration.Linq.DoNotClearOrderBys)
            {
                sequence.SelectQuery.OrderBy.Items.Clear();
            }

            foreach (var expr in sql)
            {
                // we do not need sorting by immutable values, like "Some", Func("Some"), "Some1" + "Some2". It does nothing for ordering
                //
                if (QueryHelper.IsConstant(expr.Sql))
                {
                    continue;
                }

                var e = builder.ConvertSearchCondition(expr.Sql);
                sequence.SelectQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending"));
            }

            return(sequence);
        }