internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc)
        {
            // process the arguments
            SqlExpression result = base.VisitFunctionCall(fc);

            if (result is SqlFunctionCall)
            {
                SqlFunctionCall resultFunctionCall = (SqlFunctionCall)result;

                if (resultFunctionCall.Name == "LEN")
                {
                    SqlExpression expr = resultFunctionCall.Arguments[0];

                    if (expr.SqlType.IsLargeType && !expr.SqlType.SupportsLength)
                    {
                        result = sql.DATALENGTH(expr);

                        if (expr.SqlType.IsUnicodeType)
                        {
                            result = sql.ConvertToInt(sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression)));
                        }
                    }
                }

                // If the return type of the sql function is not compatible with
                // the expected CLR type of the function, inject a conversion. This
                // step must be performed AFTER SqlRetyper has run.
                Type clrType        = resultFunctionCall.SqlType.GetClosestRuntimeType();
                bool skipConversion = SqlMethodTransformer.SkipConversionForDateAdd(resultFunctionCall.Name,
                                                                                    resultFunctionCall.ClrType,
                                                                                    clrType);
                if ((resultFunctionCall.ClrType != clrType) && !skipConversion)
                {
                    result = sql.ConvertTo(resultFunctionCall.ClrType, resultFunctionCall);
                }
            }

            return(result);
        }
Пример #2
0
            internal override SqlExpression VisitMethodCall(SqlMethodCall mc)
            {
                mc.Object = this.VisitExpression(mc.Object);
                for (int i = 0, n = mc.Arguments.Count; i < n; i++)
                {
                    mc.Arguments[i] = this.VisitExpression(mc.Arguments[i]);
                }
                if (mc.Method.IsStatic)
                {
                    if (mc.Method.Name == "Equals" && mc.Arguments.Count == 2)
                    {
                        return(sql.Binary(SqlNodeType.EQ2V, mc.Arguments[0], mc.Arguments[1], mc.Method));
                    }
                    else if (mc.Method.DeclaringType == typeof(string) && mc.Method.Name == "Concat")
                    {
                        SqlClientArray       arr   = mc.Arguments[0] as SqlClientArray;
                        List <SqlExpression> exprs = null;
                        if (arr != null)
                        {
                            exprs = arr.Expressions;
                        }
                        else
                        {
                            exprs = mc.Arguments;
                        }
                        if (exprs.Count == 0)
                        {
                            return(sql.ValueFromObject("", false, mc.SourceExpression));
                        }
                        else
                        {
                            SqlExpression sum;
                            if (exprs[0].SqlType.IsString || exprs[0].SqlType.IsChar)
                            {
                                sum = exprs[0];
                            }
                            else
                            {
                                sum = sql.ConvertTo(typeof(string), exprs[0]);
                            }
                            for (int i = 1; i < exprs.Count; i++)
                            {
                                if (exprs[i].SqlType.IsString || exprs[i].SqlType.IsChar)
                                {
                                    sum = sql.Concat(sum, exprs[i]);
                                }
                                else
                                {
                                    sum = sql.Concat(sum, sql.ConvertTo(typeof(string), exprs[i]));
                                }
                            }
                            return(sum);
                        }
                    }
                    else if (IsVbIIF(mc))
                    {
                        return(TranslateVbIIF(mc));
                    }
                    else
                    {
                        switch (mc.Method.Name)
                        {
                        case "op_Equality":
                            return(sql.Binary(SqlNodeType.EQ, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_Inequality":
                            return(sql.Binary(SqlNodeType.NE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_LessThan":
                            return(sql.Binary(SqlNodeType.LT, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_LessThanOrEqual":
                            return(sql.Binary(SqlNodeType.LE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_GreaterThan":
                            return(sql.Binary(SqlNodeType.GT, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_GreaterThanOrEqual":
                            return(sql.Binary(SqlNodeType.GE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_Multiply":
                            return(sql.Binary(SqlNodeType.Mul, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_Division":
                            return(sql.Binary(SqlNodeType.Div, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_Subtraction":
                            return(sql.Binary(SqlNodeType.Sub, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_Addition":
                            return(sql.Binary(SqlNodeType.Add, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_Modulus":
                            return(sql.Binary(SqlNodeType.Mod, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_BitwiseAnd":
                            return(sql.Binary(SqlNodeType.BitAnd, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_BitwiseOr":
                            return(sql.Binary(SqlNodeType.BitOr, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_ExclusiveOr":
                            return(sql.Binary(SqlNodeType.BitXor, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType));

                        case "op_UnaryNegation":
                            return(sql.Unary(SqlNodeType.Negate, mc.Arguments[0], mc.Method, mc.SourceExpression));

                        case "op_OnesComplement":
                            return(sql.Unary(SqlNodeType.BitNot, mc.Arguments[0], mc.Method, mc.SourceExpression));

                        case "op_False":
                            return(sql.Unary(SqlNodeType.Not, mc.Arguments[0], mc.Method, mc.SourceExpression));
                        }
                    }
                }
                else
                {
                    if (mc.Method.Name == "Equals" && mc.Arguments.Count == 1)
                    {
                        return(sql.Binary(SqlNodeType.EQ, mc.Object, mc.Arguments[0]));
                    }
                    else if (mc.Method.Name == "GetType" && mc.Arguments.Count == 0)
                    {
                        MetaType mt = TypeSource.GetSourceMetaType(mc.Object, this.model);
                        if (mt.HasInheritance)
                        {
                            Type discriminatorType             = mt.Discriminator.Type;
                            SqlDiscriminatorOf discriminatorOf = new SqlDiscriminatorOf(mc.Object, discriminatorType, this.sql.TypeProvider.From(discriminatorType), mc.SourceExpression);
                            return(this.VisitExpression(sql.DiscriminatedType(discriminatorOf, mt)));
                        }
                        return(this.VisitExpression(sql.StaticType(mt, mc.SourceExpression)));
                    }
                }
                return(mc);
            }