Ejemplo n.º 1
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequenceExpr    = methodCall.Arguments[0];
            var sequence        = builder.BuildSequence(new BuildInfo(buildInfo, sequenceExpr));
            var groupingType    = methodCall.Type.GetGenericArgumentsEx()[0];
            var keySelector     = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            var elementSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap();

            if (methodCall.Arguments[0].NodeType == ExpressionType.Call)
            {
                var call = (MethodCallExpression)methodCall.Arguments[0];

                if (call.Method.Name == "Select")
                {
                    var type = ((LambdaExpression)call.Arguments[1].Unwrap()).Body.Type;

                    if (type.IsGenericTypeEx() && type.GetGenericTypeDefinition() == typeof(ExpressionBuilder.GroupSubQuery <,>))
                    {
                        sequence = new SubQueryContext(sequence);
                    }
                }
            }

            var key      = new KeyContext(buildInfo.Parent, keySelector, sequence);
            var groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key);

            if (sequence.SelectQuery.Select.IsDistinct ||
                sequence.SelectQuery.GroupBy.Items.Count > 0 ||
                groupSql.Any(_ => !(_.Sql is SqlField || _.Sql is SelectQuery.Column)))
            {
                sequence = new SubQueryContext(sequence);
                key      = new KeyContext(buildInfo.Parent, keySelector, sequence);
                groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key);
            }

            foreach (var sql in groupSql)
            {
                sequence.SelectQuery.GroupBy.Expr(sql.Sql);
            }

            new QueryVisitor().Visit(sequence.SelectQuery.From, e =>
            {
                if (e.ElementType == QueryElementType.JoinedTable)
                {
                    var jt = (SelectQuery.JoinedTable)e;
                    if (jt.JoinType == SelectQuery.JoinType.Inner)
                    {
                        jt.IsWeak = false;
                    }
                }
            });

            var element = new SelectContext(buildInfo.Parent, elementSelector, sequence /*, key*/);
            var groupBy = new GroupByContext(buildInfo.Parent, sequenceExpr, groupingType, sequence, key, element);

            return(groupBy);
        }
Ejemplo n.º 2
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);
        }