コード例 #1
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var table    = SequenceHelper.GetTableContext(sequence) ?? throw new LinqToDBException($"Cannot get table context from {sequence.GetType()}");
            var value    = methodCall.Arguments.Count == 1 && methodCall.Method.Name == nameof(TableExtensions.IsTemporary) ?
                           true :
                           methodCall.Arguments[1].EvaluateExpression();

            switch (methodCall.Method.Name)
            {
            case nameof(LinqExtensions.TableName): table.SqlTable.PhysicalName = (string)value !; break;

            case nameof(LinqExtensions.ServerName): table.SqlTable.Server = (string?)value;  break;

            case nameof(LinqExtensions.DatabaseName): table.SqlTable.Database = (string?)value;  break;

            case nameof(LinqExtensions.SchemaName): table.SqlTable.Schema = (string?)value;  break;

            case nameof(TableExtensions.TableOptions): table.SqlTable.TableOptions = (TableOptions)value !; break;

            case nameof(TableExtensions.IsTemporary): table.SqlTable.Set((bool)value !, TableOptions.IsTemporary); break;
            }

            return(sequence);
        }
コード例 #2
0
        public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags)
        {
            expression = SequenceHelper.CorrectExpression(expression, this, Context);

            var indexes = SubQuery
                          .ConvertToIndex(expression, level, flags)
                          .ToArray();

            var result = indexes
                         .Select(idx => new SqlInfo(idx.MemberChain, idx.Index < 0 ? idx.Sql : SubQuery.SelectQuery.Select.Columns[idx.Index], idx.Index))
                         .ToArray();

            return(result);
        }
コード例 #3
0
        public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags)
        {
            expression = SequenceHelper.CorrectExpression(expression, this, SubQuery);

            return(SubQuery
                   .ConvertToIndex(expression, level, flags)
                   .Select(info =>
            {
                var expr = (info.Sql is SqlColumn column) ? column.Expression : info.Sql;
                var field = RegisterSourceField(expr, expr, info.Index, info.MemberChain.LastOrDefault());

                return new SqlInfo(info.MemberChain, field);
            })
                   .ToArray());
        }
コード例 #4
0
            Expression BuildExpression(int fieldIndex, ISqlExpression?sqlExpression)
            {
                Expression expr;

                if (SequenceHelper.UnwrapSubqueryContext(Sequence) is DefaultIfEmptyBuilder.DefaultIfEmptyContext defaultIfEmpty)
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                    if (defaultIfEmpty.DefaultValue != null && expr is ConvertFromDataReaderExpression convert)
                    {
                        var generator = new ExpressionGenerator();
                        expr = convert.MakeNullable();
                        if (expr.Type.IsNullable())
                        {
                            var exprVar      = generator.AssignToVariable(expr, "nullable");
                            var defaultValue = defaultIfEmpty.DefaultValue;
                            if (defaultValue.Type != expr.Type)
                            {
                                var convertLambda = Builder.MappingSchema.GenerateSafeConvert(defaultValue.Type, expr.Type);
                                defaultValue = InternalExtensions.ApplyLambdaToExpression(convertLambda, defaultValue);
                            }

                            var resultVar = generator.AssignToVariable(defaultValue, "result");

                            generator.AddExpression(Expression.IfThen(
                                                        Expression.NotEqual(exprVar, ExpressionInstances.UntypedNull),
                                                        Expression.Assign(resultVar, Expression.Convert(exprVar, resultVar.Type))));

                            generator.AddExpression(resultVar);

                            expr = generator.Build();
                        }
                    }
                }
                else
                if (_methodName == "Sum" || _returnType.IsNullableType())
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                }
                else
                {
                    expr = Expression.Block(
                        Expression.Call(null, MemberHelper.MethodOf(() => CheckNullValue(false, null !)), Expression.Call(ExpressionBuilder.DataReaderParam, Methods.ADONet.IsDBNull, ExpressionInstances.Constant0), Expression.Constant(_methodName)),
                        Builder.BuildSql(_returnType, fieldIndex, sqlExpression));
                }

                return(expr);
            }
コード例 #5
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var table    = SequenceHelper.GetTableContext(sequence) ?? throw new LinqToDBException($"Cannot get table context from {sequence.GetType()}");
            var value    = (string)methodCall.Arguments[1].EvaluateExpression() !;

            table.SqlTable.SqlTableType   = SqlTableType.Expression;
            table.SqlTable.TableArguments = Array <ISqlExpression> .Empty;

            switch (methodCall.Method.Name)
            {
            case "With": table.SqlTable.Name = $"{{0}} {{1}} WITH ({value})"; break;

            case "WithTableExpression": table.SqlTable.Name = value;                         break;
            }

            return(sequence);
        }
コード例 #6
0
            public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags)
            {
                var queryContext = GetQueryContext();

                if (queryContext == null)
                {
                    return(base.ConvertToSql(expression, level, flags));
                }

                var baseInfos = base.ConvertToSql(null, 0, ConvertFlags.All);

                if (flags != ConvertFlags.All && _cte.Fields !.Length == 0 && queryContext.SelectQuery.Select.Columns.Count > 0)
                {
                    // it means that queryContext context already has columns and we need all of them. For example for Distinct.
                    ConvertToSql(null, 0, ConvertFlags.All);
                }

                expression = SequenceHelper.CorrectExpression(expression, this, queryContext);

                var infos = queryContext.ConvertToIndex(expression, level, flags);

                var result = infos
                             .Select(info =>
                {
                    var baseInfo = baseInfos.FirstOrDefault(bi => bi.CompareMembers(info));
                    var alias    = flags == ConvertFlags.Field ? GenerateAlias(expression) : null;
                    if (alias == null)
                    {
                        alias = baseInfo?.MemberChain.LastOrDefault()?.Name ??
                                info.MemberChain.LastOrDefault()?.Name;
                    }
                    var field = RegisterCteField(baseInfo?.Sql, info.Sql, info.Index, alias);
                    return(new SqlInfo(info.MemberChain, field));
                })
                             .ToArray();

                return(result);
            }
コード例 #7
0
            public override Expression BuildExpression(Expression?expression, int level, bool enforceServerSide)
            {
                expression = SequenceHelper.CorrectExpression(expression, this, Sequence);

                var expr = Sequence.BuildExpression(expression, level, enforceServerSide);

                if (!Disabled && expression == null)
                {
                    var q =
                        from col in SelectQuery.Select.Columns
                        where !col.CanBeNull
                        select SelectQuery.Select.Columns.IndexOf(col);

                    var idx = q.DefaultIfEmpty(-1).First();

                    if (idx == -1)
                    {
                        idx = SelectQuery.Select.Add(new SqlValue((int?)1));
                        SelectQuery.Select.Columns[idx].RawAlias = "is_empty";
                    }

                    var n = ConvertToParentIndex(idx, this);

                    Expression e = Expression.Call(
                        ExpressionBuilder.DataReaderParam,
                        ReflectionHelper.DataReader.IsDBNull,
                        ExpressionInstances.Int32Array(n));

                    var defaultValue = DefaultValue ?? new DefaultValueExpression(Builder.MappingSchema, expr.Type);

                    if (expr.NodeType == ExpressionType.Parameter)
                    {
                        var par  = (ParameterExpression)expr;
                        var pidx = Builder.BlockVariables.IndexOf(par);

                        if (pidx >= 0)
                        {
                            var ex = Builder.BlockExpressions[pidx];

                            if (ex.NodeType == ExpressionType.Assign)
                            {
                                var bex = (BinaryExpression)ex;

                                if (bex.Left == expr)
                                {
                                    if (bex.Right.NodeType != ExpressionType.Conditional)
                                    {
                                        Builder.BlockExpressions[pidx] =
                                            Expression.Assign(
                                                bex.Left,
                                                Expression.Condition(e, defaultValue, bex.Right));
                                    }
                                }
                            }
                        }
                    }

                    expr = Expression.Condition(e, defaultValue, expr);
                }

                return(expr);
            }
コード例 #8
0
 public override IBuildContext?GetContext(Expression?expression, int level, BuildInfo buildInfo)
 {
     expression = SequenceHelper.CorrectExpression(expression, this, Sequence);
     return(Sequence.GetContext(expression, level, buildInfo));
 }
コード例 #9
0
 public override IsExpressionResult IsExpression(Expression?expression, int level, RequestFor requestFlag)
 {
     expression = SequenceHelper.CorrectExpression(expression, this, Sequence);
     return(Sequence.IsExpression(expression, level, requestFlag));
 }
コード例 #10
0
 public override SqlInfo[] ConvertToIndex(Expression?expression, int level, ConvertFlags flags)
 {
     expression = SequenceHelper.CorrectExpression(expression, this, Sequence);
     return(Sequence.ConvertToIndex(expression, level, flags));
 }