示例#1
0
        public override DbExpression Visit(DbEqualExpression exp)
        {
            DbExpression left  = exp.Left;
            DbExpression right = exp.Right;

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

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

            /* Sql.Equals(left, right) */
            DbMethodCallExpression left_equals_right = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2)
            {
                left, right
            });

            if (right.NodeType == DbExpressionType.Parameter || right.NodeType == DbExpressionType.Constant || left.NodeType == DbExpressionType.Parameter || left.NodeType == DbExpressionType.Constant || right.NodeType == DbExpressionType.SubQuery || left.NodeType == DbExpressionType.SubQuery || !left.Type.CanNull() || !right.Type.CanNull())
            {
                /*
                 * a.Name == name --> a.Name == name
                 * a.Id == (select top 1 T.Id from T) --> a.Id == (select top 1 T.Id from T)
                 * 对于上述查询,我们不考虑 null
                 */

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


            /*
             * a.Name == a.XName --> a.Name == a.XName or (a.Name is null and a.XName is null)
             */

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

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

            /* Sql.Equals(left, null) && Sql.Equals(right, null) */
            var left_is_null_and_right_is_null = DbExpression.And(left_is_null, right_is_null);

            /* Sql.Equals(left, right) || (Sql.Equals(left, null) && Sql.Equals(right, null)) */
            var left_equals_right_or_left_is_null_and_right_is_null = DbExpression.Or(left_equals_right, left_is_null_and_right_is_null);

            left_equals_right_or_left_is_null_and_right_is_null.Accept(this);

            return(exp);
        }
示例#2
0
        public override DbExpression Visit(DbNotEqualExpression exp)
        {
            /*
             * join 的条件不考虑 null 问题
             */

            DbExpression left  = exp.Left;
            DbExpression right = exp.Right;

            MethodInfo method_Sql_NotEquals = UtilConstants.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.Accept(this), right.Accept(this)
            });

            return(left_not_equals_right);
        }
        public override DbExpression Visit(DbMethodCallExpression exp)
        {
            var          args   = exp.Arguments.Select(a => a.Accept(this)).ToList();
            DbExpression caller = exp.Object;

            if (exp.Object != null)
            {
                caller = exp.Object.Accept(this);
            }

            exp = DbExpression.MethodCall(caller, exp.Method, args);

            if (exp.Object != null)
            {
                if (!IsConstantOrParameter(exp.Object))
                {
                    return(exp);
                }
            }

            foreach (var arg in exp.Arguments)
            {
                if (!IsConstantOrParameter(arg))
                {
                    return(exp);
                }
            }

            if (this.CanTranslateToSql(exp))
            {
                return(exp);
            }

            if (exp.Method.IsDefined(typeof(DbFunctionAttribute)))
            {
                return(exp);
            }

            return(DbExpression.Parameter(exp.Evaluate(), exp.Type));
        }
示例#4
0
        public void Process(DbMethodCallExpression exp, SqlGenerator generator)
        {
            DbExpression left  = exp.Arguments[0];
            DbExpression right = exp.Arguments[2];

            CompareType compareType = (CompareType)exp.Arguments[1].Evaluate();

            DbExpression newExp = null;

            switch (compareType)
            {
            case CompareType.eq:
            {
                MethodInfo method_Sql_Equals = PublicConstants.MethodInfo_Sql_Equals.MakeGenericMethod(left.Type);

                /* Sql.Equals(left, right) */
                DbMethodCallExpression left_equals_right = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2)
                    {
                        left, right
                    });

                newExp = left_equals_right;
            }
            break;

            case CompareType.neq:
            {
                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
                    });

                newExp = left_not_equals_right;
            }
            break;

            case CompareType.gt:
            {
                newExp = new DbGreaterThanExpression(left, right);
            }
            break;

            case CompareType.gte:
            {
                newExp = new DbGreaterThanOrEqualExpression(left, right);
            }
            break;

            case CompareType.lt:
            {
                newExp = new DbLessThanExpression(left, right);
            }
            break;

            case CompareType.lte:
            {
                newExp = new DbLessThanOrEqualExpression(left, right);
            }
            break;

            default:
                throw new NotSupportedException("CompareType: " + compareType.ToString());
            }

            newExp.Accept(generator);
        }
示例#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);
        }