internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
     if (this.isDebugMode) {
         sb.Append("DISCO(");
     }
     base.VisitDiscriminatorOf(dof);
     if (this.isDebugMode) {
         sb.Append(")");
     }
     return dof;
 }
            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));
                    }
                    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));
                        }
                        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);
                    }
                    if (IsVbIIF(mc))
                    {
                        return(TranslateVbIIF(mc));
                    }
                    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]));
                    }
                    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);
            }
Example #3
0
 internal virtual SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
     dof.Object = this.VisitExpression(dof.Object);
     return dof;
 }
 internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
     return new SqlDiscriminatorOf(this.VisitExpression(dof.Object), dof.ClrType, dof.SqlType, dof.SourceExpression);
 }
 /// <summary>
 /// Evaluate the object and extract its discriminator.
 /// </summary>
 internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
     SqlExpression obj = this.FetchExpression(dof.Object); // FetchExpression removes Link.
     // It's valid to unwrap optional and outer-join values here because type case already handles
     // NULL values correctly.
     while (obj.NodeType == SqlNodeType.OptionalValue
         || obj.NodeType == SqlNodeType.OuterJoinedValue) {
         if (obj.NodeType == SqlNodeType.OptionalValue) {
             obj = ((SqlOptionalValue)obj).Value;
         }
         else {
             obj = ((SqlUnary)obj).Operand;
         }
     }
     if (obj.NodeType == SqlNodeType.TypeCase) {
         SqlTypeCase tc = (SqlTypeCase)obj;
         // Rewrite a case of discriminators. We can't just reduce to 
         // discriminator (yet) because the ELSE clause needs to be considered.
         // Later in the conversion there is an optimization that will turn the CASE
         // into a simple combination of ANDs and ORs.
         // Also, cannot reduce to IsNull(Discriminator,DefaultDiscriminator) because
         // other unexpected values besides NULL need to be handled.
         List<SqlExpression> matches = new List<SqlExpression>();
         List<SqlExpression> values = new List<SqlExpression>();
         MetaType defaultType = tc.RowType.InheritanceDefault;
         object discriminator = defaultType.InheritanceCode;
         foreach (SqlTypeCaseWhen when in tc.Whens) {
             matches.Add(when.Match);
             if (when.Match == null) {
                 SqlExpression @default = sql.Value(discriminator.GetType(), tc.Whens[0].Match.SqlType, defaultType.InheritanceCode, true, tc.SourceExpression);
                 values.Add(@default);
             }
             else {
                 // Must duplicate so that columnizer doesn't nominate the match as a value.
                 values.Add(sql.Value(discriminator.GetType(), when.Match.SqlType, ((SqlValue)when.Match).Value, true, tc.SourceExpression));
             }
         }
         return sql.Case(tc.Discriminator.ClrType, tc.Discriminator, matches, values, tc.SourceExpression);
     } else {
         var mt = this.model.GetMetaType(obj.ClrType).InheritanceRoot;
         if (mt.HasInheritance) {
             return this.VisitExpression(sql.Member(dof.Object, mt.Discriminator.Member));
         }
     }
     return sql.TypedLiteralNull(dof.ClrType, dof.SourceExpression);
 }
 internal virtual SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
     dof.Object = this.VisitExpression(dof.Object);
     return dof;
 }
 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;
 }
 internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof)
 {
     return(new SqlDiscriminatorOf(this.VisitExpression(dof.Object), dof.ClrType, dof.SqlType, dof.SourceExpression));
 }