Example #1
0
        public void Process(DbMethodCallExpression exp, SqlGenerator generator)
        {
            DbExpression      e = exp.Arguments.First();
            DbEqualExpression equalNullExpression  = DbExpression.Equal(e, DbExpression.Constant(null, PublicConstants.TypeOfString));
            DbEqualExpression equalEmptyExpression = DbExpression.Equal(e, DbExpression.Constant(string.Empty));

            DbOrExpression orExpression = DbExpression.Or(equalNullExpression, equalEmptyExpression);

            DbCaseWhenExpression.WhenThenExpressionPair whenThenPair = new DbCaseWhenExpression.WhenThenExpressionPair(orExpression, DbConstantExpression.One);

            List <DbCaseWhenExpression.WhenThenExpressionPair> whenThenExps = new List <DbCaseWhenExpression.WhenThenExpressionPair>(1);

            whenThenExps.Add(whenThenPair);

            DbCaseWhenExpression caseWhenExpression = DbExpression.CaseWhen(whenThenExps, DbConstantExpression.Zero, PublicConstants.TypeOfBoolean);

            var eqExp = DbExpression.Equal(caseWhenExpression, DbConstantExpression.One);

            eqExp.Accept(generator);
        }
Example #2
0
        public override DbExpression Visit(DbExistsExpression exp)
        {
            this.SqlBuilder.Append("Exists ");

            DbSqlQueryExpression rawSqlQuery = exp.SqlQuery;
            DbSqlQueryExpression sqlQuery    = new DbSqlQueryExpression()
            {
                TakeCount       = rawSqlQuery.TakeCount,
                SkipCount       = rawSqlQuery.SkipCount,
                Table           = rawSqlQuery.Table,
                Condition       = rawSqlQuery.Condition,
                HavingCondition = rawSqlQuery.HavingCondition,
            };

            sqlQuery.GroupSegments.AddRange(rawSqlQuery.GroupSegments);

            DbColumnSegment columnSegment = new DbColumnSegment(DbExpression.Constant("1"), "C");

            sqlQuery.ColumnSegments.Add(columnSegment);

            DbSubQueryExpression subQuery = new DbSubQueryExpression(sqlQuery);

            return(subQuery.Accept(this));
        }
        public override object Visit(DbConvertExpression exp)
        {
            object operandValue = exp.Operand.Accept(this);

            //(int)null
            if (operandValue == null)
            {
                //(int)null
                if (exp.Type.IsValueType && !exp.Type.IsNullable())
                {
                    throw new NullReferenceException();
                }

                return(null);
            }

            Type operandValueType = operandValue.GetType();

            if (exp.Type == operandValueType || exp.Type.IsAssignableFrom(operandValueType))
            {
                return(operandValue);
            }

            Type underlyingType;

            if (exp.Type.IsNullable(out underlyingType))
            {
                //(int?)int
                if (underlyingType == operandValueType)
                {
                    var constructor = exp.Type.GetConstructor(new Type[] { operandValueType });
                    var val         = constructor.Invoke(new object[] { operandValue });
                    return(val);
                }
                else
                {
                    //如果不等,则诸如:(long?)int / (long?)int?  -->  (long?)((long)int) / (long?)((long)int?)
                    var c  = DbExpression.Convert(DbExpression.Constant(operandValue), underlyingType);
                    var cc = DbExpression.Convert(c, exp.Type);
                    return(this.Visit(cc));
                }
            }

            //(int)int?
            if (operandValueType.IsNullable(out underlyingType))
            {
                if (underlyingType == exp.Type)
                {
                    var pro = operandValueType.GetProperty("Value");
                    var val = pro.GetValue(operandValue, null);
                    return(val);
                }
                else
                {
                    //如果不等,则诸如:(long)int?  -->  (long)((long)int)
                    var c  = DbExpression.Convert(DbExpression.Constant(operandValue), underlyingType);
                    var cc = DbExpression.Convert(c, exp.Type);
                    return(this.Visit(cc));
                }
            }

            if (exp.Type.IsEnum)
            {
                return(Enum.ToObject(exp.Type, operandValue));
            }

            //(long)int
            if (operandValue is IConvertible)
            {
                return(Convert.ChangeType(operandValue, exp.Type));
            }

            throw new NotSupportedException(string.Format("Does not support the type '{0}' converted to type '{1}'.", operandValueType.FullName, exp.Type.FullName));
        }
Example #4
0
        public void Process(DbMethodCallExpression exp, SqlGeneratorBase generator)
        {
            MethodInfo method = exp.Method;

            if (exp.Method == PublicConstants.MethodInfo_String_Contains)
            {
                Method_String_Contains(exp, generator);
                return;
            }

            List <DbExpression> exps    = new List <DbExpression>();
            IEnumerable         values  = null;
            DbExpression        operand = null;

            Type declaringType = method.DeclaringType;

            if (typeof(IList).IsAssignableFrom(declaringType) || (declaringType.IsGenericType && typeof(ICollection <>).MakeGenericType(declaringType.GetGenericArguments()).IsAssignableFrom(declaringType)))
            {
                if (exp.Object.NodeType == DbExpressionType.SqlQuery)
                {
                    /* where Id in(select id from T) */

                    operand = exp.Arguments[0];
                    In(generator, (DbSqlQueryExpression)exp.Object, operand);
                    return;
                }

                if (!exp.Object.IsEvaluable())
                {
                    throw new NotSupportedException(exp.ToString());
                }

                values  = DbExpressionExtension.Evaluate(exp.Object) as IEnumerable; //Enumerable
                operand = exp.Arguments[0];
                goto constructInState;
            }
            if (method.IsStatic && declaringType == typeof(Enumerable) && exp.Arguments.Count == 2)
            {
                DbExpression arg0 = exp.Arguments[0];
                if (arg0.NodeType == DbExpressionType.SqlQuery)
                {
                    /* where Id in(select id from T) */

                    operand = exp.Arguments[1];
                    In(generator, (DbSqlQueryExpression)arg0, operand);
                    return;
                }

                if (!arg0.IsEvaluable())
                {
                    throw UtilExceptions.NotSupportedMethod(exp.Method);
                }

                values  = DbExpressionExtension.Evaluate(arg0) as IEnumerable;
                operand = exp.Arguments[1];
                goto constructInState;
            }

            throw UtilExceptions.NotSupportedMethod(exp.Method);

constructInState:
            foreach (object value in values)
            {
                if (value == null)
                {
                    exps.Add(DbExpression.Constant(null, operand.Type));
                }
                else
                {
                    Type valueType = value.GetType();
                    if (valueType.IsEnum)
                    {
                        valueType = Enum.GetUnderlyingType(valueType);
                    }

                    if (Utils.IsToStringableNumericType(valueType))
                    {
                        exps.Add(DbExpression.Constant(value));
                    }
                    else
                    {
                        exps.Add(DbExpression.Parameter(value));
                    }
                }
            }

            In(generator, exps, operand);
        }
Example #5
0
        public override DbExpression Visit(DbNotEqualExpression exp)
        {
            DbExpression left  = exp.Left;
            DbExpression right = exp.Right;

            left  = DbExpressionExtension.StripInvalidConvert(left);
            right = DbExpressionExtension.StripInvalidConvert(right);

            MethodInfo method_Sql_NotEquals = PublicConstants.MethodInfo_Sql_NotEquals.MakeGenericMethod(left.Type);

            /* Sql.NotEquals(left, right) */
            DbMethodCallExpression left_not_equals_right = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2)
            {
                left, right
            });

            //明确 left right 其中一边一定为 null
            if (DbExpressionExtension.AffirmExpressionRetValueIsNull(right) || DbExpressionExtension.AffirmExpressionRetValueIsNull(left))
            {
                /*
                 * a.Name != null --> a.Name != null
                 */

                left_not_equals_right.Accept(this);
                return(exp);
            }

            if (right.NodeType == DbExpressionType.SubQuery || left.NodeType == DbExpressionType.SubQuery)
            {
                /*
                 * a.Id != (select top 1 T.Id from T) --> a.Id <> (select top 1 T.Id from T),对于这种查询,我们不考虑 null
                 */

                left_not_equals_right.Accept(this);
                return(exp);
            }

            MethodInfo method_Sql_Equals = PublicConstants.MethodInfo_Sql_Equals.MakeGenericMethod(left.Type);

            if (left.NodeType == DbExpressionType.Parameter || left.NodeType == DbExpressionType.Constant)
            {
                var t = right;
                right = left;
                left  = t;
            }
            if (right.NodeType == DbExpressionType.Parameter || right.NodeType == DbExpressionType.Constant)
            {
                /*
                 * 走到这说明 name 不可能为 null
                 * a.Name != name --> a.Name <> name or a.Name is null
                 */

                if (left.NodeType != DbExpressionType.Parameter && left.NodeType != DbExpressionType.Constant)
                {
                    /*
                     * a.Name != name --> a.Name <> name or a.Name is null
                     */

                    /* Sql.Equals(left, null) */
                    var left_is_null1 = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2)
                    {
                        left, DbExpression.Constant(null, left.Type)
                    });

                    /* Sql.NotEquals(left, right) || Sql.Equals(left, null) */
                    var left_not_equals_right_or_left_is_null = DbExpression.Or(left_not_equals_right, left_is_null1);
                    left_not_equals_right_or_left_is_null.Accept(this);
                }
                else
                {
                    /*
                     * name != name1 --> name <> name,其中 name 和 name1 都为变量且都不可能为 null
                     */

                    left_not_equals_right.Accept(this);
                }

                return(exp);
            }


            /*
             * a.Name != a.XName --> a.Name <> a.XName or (a.Name is null and a.XName is not null) or (a.Name is not null and a.XName is null)
             * ## a.Name != a.XName 不能翻译成:not (a.Name == a.XName or (a.Name is null and a.XName is null)),因为数据库里的 not 有时候并非真正意义上的“取反”!
             * 当 a.Name 或者 a.XName 其中一个字段有为 NULL,另一个字段有值时,会查不出此条数据 ##
             */

            DbConstantExpression null_Constant = DbExpression.Constant(null, left.Type);

            /* Sql.Equals(left, null) */
            var left_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2)
            {
                left, null_Constant
            });
            /* Sql.NotEquals(left, null) */
            var left_is_not_null = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2)
            {
                left, null_Constant
            });

            /* Sql.Equals(right, null) */
            var right_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2)
            {
                right, null_Constant
            });
            /* Sql.NotEquals(right, null) */
            var right_is_not_null = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2)
            {
                right, null_Constant
            });

            /* Sql.Equals(left, null) && Sql.NotEquals(right, null) */
            var left_is_null_and_right_is_not_null = DbExpression.And(left_is_null, right_is_not_null);

            /* Sql.NotEquals(left, null) && Sql.Equals(right, null) */
            var left_is_not_null_and_right_is_null = DbExpression.And(left_is_not_null, right_is_null);

            /* (Sql.Equals(left, null) && Sql.NotEquals(right, null)) || (Sql.NotEquals(left, null) && Sql.Equals(right, null)) */
            var left_is_null_and_right_is_not_null_or_left_is_not_null_and_right_is_null = DbExpression.Or(left_is_null_and_right_is_not_null, left_is_not_null_and_right_is_null);

            /* Sql.NotEquals(left, right) || (Sql.Equals(left, null) && Sql.NotEquals(right, null)) || (Sql.NotEquals(left, null) && Sql.Equals(right, null)) */
            var e = DbExpression.Or(left_not_equals_right, left_is_null_and_right_is_not_null_or_left_is_not_null_and_right_is_null);

            e.Accept(this);

            return(exp);
        }
Example #6
0
        static void AppendLimitCondition(DbSqlQueryExpression sqlQuery, int limitCount)
        {
            DbLessThanExpression lessThanExp = DbExpression.LessThan(OracleSemantics.DbMemberExpression_ROWNUM, DbExpression.Constant(limitCount + 1));

            DbExpression condition = lessThanExp;

            if (sqlQuery.Condition != null)
            {
                condition = DbExpression.And(sqlQuery.Condition, condition);
            }

            sqlQuery.Condition = condition;
        }