Пример #1
0
            public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
            {
                if (expression == null && buildInfo != null)
                {
                    if (buildInfo.Parent is SelectManyBuilder.SelectManyContext)
                    {
                        var sm     = (SelectManyBuilder.SelectManyContext)buildInfo.Parent;
                        var ctype  = typeof(ContextHelper <>).MakeGenericType(_key.Lambda.Parameters[0].Type);
                        var helper = (IContextHelper)Activator.CreateInstance(ctype);
                        var expr   = helper.GetContext(
                            Sequence.Expression,
                            _key.Lambda.Parameters[0],
                            Expression.PropertyOrField(sm.Lambda.Parameters[0], "Key"),
                            _key.Lambda.Body);

                        return(Builder.BuildSequence(new BuildInfo(buildInfo, expr)));
                    }

                    //if (buildInfo.Parent == this)
                    {
                        var ctype  = typeof(ContextHelper <>).MakeGenericType(_key.Lambda.Parameters[0].Type);
                        var helper = (IContextHelper)Activator.CreateInstance(ctype);
                        var expr   = helper.GetContext(
                            _sequenceExpr,
                            _key.Lambda.Parameters[0],
                            Expression.PropertyOrField(buildInfo.Expression, "Key"),
                            _key.Lambda.Body);

                        var ctx = Builder.BuildSequence(new BuildInfo(buildInfo, expr));

                        ctx.SelectQuery.Properties.Add(Tuple.Create("from_group_by", SelectQuery));

                        return(ctx);
                    }

                    //return this;
                }

                if (level != 0)
                {
                    var levelExpression = expression.GetLevelExpression(level);

                    if (levelExpression.NodeType == ExpressionType.MemberAccess)
                    {
                        var ma = (MemberExpression)levelExpression;

                        if (ma.Member.Name == "Key" && ma.Member.DeclaringType == _groupingType)
                        {
                            return(ReferenceEquals(levelExpression, expression) ?
                                   _key.GetContext(null, 0, buildInfo) :
                                   _key.GetContext(expression, level + 1, buildInfo));
                        }
                    }
                }

                throw new NotImplementedException();
            }
Пример #2
0
        protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            if (!methodCall.IsQueryable("GroupBy"))
            {
                return(false);
            }

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

            if (body.NodeType == ExpressionType.MemberInit)
            {
                var  mi = (MemberInitExpression)body;
                bool throwExpr;

                if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0)
                {
                    throwExpr = true;
                }
                else
                {
                    throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment);
                }

                if (throwExpr)
                {
                    throw new NotSupportedException("Explicit construction of entity type '{0}' in group by is not allowed.".Args(body.Type));
                }
            }

            return(methodCall.Arguments[methodCall.Arguments.Count - 1].Unwrap().NodeType == ExpressionType.Lambda);
        }
Пример #3
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);
        }
Пример #4
0
 protected override SequenceConvertInfo Convert(
     ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
 {
     return(null);
 }
Пример #5
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.IsDistinct ||
                sequence.SelectQuery.Select.TakeValue != null ||
                sequence.SelectQuery.Select.SkipValue != null ||
                !sequence.SelectQuery.GroupBy.IsEmpty)
            {
                sequence = new SubQueryContext(sequence);
            }

            if (sequence.SelectQuery.OrderBy.Items.Count > 0)
            {
                if (sequence.SelectQuery.Select.TakeValue == null && sequence.SelectQuery.Select.SkipValue == null)
                {
                    sequence.SelectQuery.OrderBy.Items.Clear();
                }
                else
                {
                    sequence = new SubQueryContext(sequence);
                }
            }

            var context = new AggregationContext(buildInfo.Parent, sequence, methodCall);
            var sql     = sequence.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray();

            if (sql.Length == 1 && sql[0] is SelectQuery)
            {
                var query = (SelectQuery)sql[0];

                if (query.Select.Columns.Count == 1)
                {
                    var join = SelectQuery.OuterApply(query);
                    context.SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable);
                    sql[0] = query.Select.Columns[0];
                }
            }

            context.Sql        = context.SelectQuery;
            context.FieldIndex = context.SelectQuery.Select.Add(
                new SqlFunction(methodCall.Type, methodCall.Method.Name, sql));

            return(context);
        }
Пример #6
0
 public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
 {
     throw new NotImplementedException();
 }
Пример #7
0
 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
 {
     return(methodCall.IsQueryable(MethodNames));
 }
Пример #8
0
 public BuildInfo(BuildInfo buildInfo, Expression expression, SelectQuery selectQuery)
     : this(buildInfo.Parent, expression, selectQuery)
 {
     SequenceInfo   = buildInfo;
     CreateSubQuery = buildInfo.CreateSubQuery;
 }