protected virtual void VisitConstant(ConstantExpression c, SqlVistorFlag flag)
        {
            var value = c.Value ?? "null";

            if (flag.is_right)
            {
                var paraName = GetCustomParaName(flag.para_pretoken); // flag.GetCustomParaName();
                flag.Append(paraName, true);

                if (c.Type.IsEnum)
                {
                    AddParameter(paraName, (int)c.Value);
                }
                else if (c.Type == typeof(bool))
                {
                    AddParameter(paraName, (bool)value ? 1 : 0);
                }
                else
                {
                    AddParameter(paraName, value);
                }
            }
            else
            {
                flag.Append(value.ToString());
            }
        }
        protected virtual void VisitUnary(UnaryExpression u, SqlVistorFlag flag)
        {
            var nodeType = flag.unary_type;

            flag.unary_type = u.NodeType;
            Visit(u.Operand, flag);
            flag.unary_type = nodeType;
        }
 private void MethodCallLike(MethodCallExpression exp, SqlVistorFlag flag)
 {
     Visit(exp.Object, flag);
     flag.Append(GetUnaryOperater(flag.unary_type));
     flag.Append(" LIKE CONCAT('%',");
     VisitRight(exp.Arguments[0], flag);
     flag.Append(",'%')");
 }
        /// <summary>
        ///   递归解析时,保留上层的IsRight状态
        /// </summary>
        /// <param name="exp"></param>
        /// <param name="flag"></param>
        protected virtual void VisitRight(Expression exp, SqlVistorFlag flag)
        {
            var isRight = flag.is_right;

            flag.is_right = true;
            Visit(exp, flag);
            flag.is_right = isRight; //  回归
        }
        protected virtual void VisitNew(NewExpression nex, SqlVistorFlag flag)
        {
            for (var i = 0; i < nex.Members.Count; i++)
            {
                var arg    = nex.Arguments[i];
                var member = nex.Members[i];

                flag.Append(flag.GetColName(member.Name)).Append("=");
                VisitRight(arg, flag);
            }
        }
        protected virtual void VisitMethodCall(MethodCallExpression exp, SqlVistorFlag flag)
        {
            var methodName = exp.Method.Name;

            switch (methodName) //这里其实还可以改成反射调用,不用写switch
            {
            case "Contains":
                MethodCallLike(exp, flag);
                break;

                //  todo 补充其他方法
            }
        }
        protected virtual void VisitMember(MemberExpression exp, SqlVistorFlag flag)
        {
            if (exp.Expression != null &&
                exp.Expression.NodeType == ExpressionType.Parameter)
            {
                if (flag.is_right && flag.vistor_type == SqlVistorType.Update)
                {
                    var proParaName = flag.GetParaName(exp.Member.Name);
                    flag.Append(proParaName, true);

                    AddMemberProperty(proParaName, exp.Member.Name);
                }
                else
                {
                    if (exp.Member.DeclaringType.GetTypeInfo().IsGenericType &&
                        exp.Member.DeclaringType?.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        if (exp.Member.Name == "Value")
                        {
                            Visit(exp.Expression, flag);
                        }

                        if (exp.Member.Name != "HasValue")
                        {
                            return;
                        }

                        var doesNotEqualNull = Expression.MakeBinary(ExpressionType.NotEqual, exp.Expression,
                                                                     Expression.Constant(null));
                        Visit(doesNotEqualNull, flag);
                    }
                    else
                    {
                        flag.Append(flag.GetColName(exp.Member.Name), true);
                    }
                }
            }
            else
            {
                var value = Expression.Lambda(exp).Compile().DynamicInvoke();
                Visit(Expression.Constant(value), flag);
            }
        }
        protected void VisitNewArray(NewArrayExpression na, SqlVistorFlag flag)
        {
            var original = na.Expressions;

            for (int i = 0, n = original.Count; i < n; i++)
            {
                var e = original[i];
                if (e.NodeType == ExpressionType.NewArrayInit ||
                    e.NodeType == ExpressionType.NewArrayBounds)
                {
                    if (e is NewArrayExpression newArrayExpression)
                    {
                        VisitNewArray(newArrayExpression, flag);
                    }
                }
                else
                {
                    Visit(e, flag);
                }
            }
        }
        protected virtual void VisitBinary(BinaryExpression exp, SqlVistorFlag flag)
        {
            var operand = GetBinaryOperater(exp.NodeType);

            if (exp.NodeType == ExpressionType.AndAlso ||
                exp.NodeType == ExpressionType.OrElse)
            {
                flag.Append("(");
                Visit(exp.Left, flag);

                flag.Append(") ").Append(operand).Append(" (");
                Visit(exp.Right, flag);
                flag.Append(")");
            }
            else
            {
                Visit(exp.Left, flag);
                flag.Append(operand);
                VisitRight(exp.Right, flag);
            }
        }
Example #10
0
        /// <summary>
        ///   处理where条件表达式,如果表达式为空,默认使用Id
        /// </summary>
        /// <param name="visitor"></param>
        /// <param name="exp"></param>
        /// <param name="visType"></param>
        private static string GetVisitExpressSql(SqlExpressionVisitor visitor, Expression exp, SqlVistorType visType)
        {
            if (visType == SqlVistorType.Update)
            {
                var updateFlag = new SqlVistorFlag(SqlVistorType.Update);
                visitor.Visit(exp, updateFlag);
                return(updateFlag.sql);
            }

            string sql;

            if (exp == null)
            {
                throw new ArgumentNullException("whereExp", "where表达式不能为空!");
            }
            else
            {
                var whereFlag = new SqlVistorFlag(SqlVistorType.Where);
                visitor.Visit(exp, whereFlag);
                sql = string.Concat(" WHERE ", whereFlag.sql);
            }

            return(sql);
        }
        /// <summary>
        ///  递归解析方法入口
        /// </summary>
        /// <param name="exp"></param>
        /// <param name="flag"></param>
        public virtual void Visit(Expression exp, SqlVistorFlag flag)
        {
            switch (exp.NodeType)
            {
            case ExpressionType.Lambda:
                VisitLambda(exp as LambdaExpression, flag);
                break;

            case ExpressionType.MemberAccess:
                VisitMember(exp as MemberExpression, flag);
                break;

            case ExpressionType.Add:
            case ExpressionType.AddChecked:
            case ExpressionType.Subtract:
            case ExpressionType.SubtractChecked:
            case ExpressionType.Multiply:
            case ExpressionType.MultiplyChecked:
            case ExpressionType.Divide:
            case ExpressionType.Modulo:
            case ExpressionType.And:
            case ExpressionType.AndAlso:
            case ExpressionType.Or:
            case ExpressionType.OrElse:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.Equal:
            case ExpressionType.NotEqual:
            case ExpressionType.Coalesce:
            case ExpressionType.ArrayIndex:
            case ExpressionType.RightShift:
            case ExpressionType.LeftShift:
            case ExpressionType.ExclusiveOr:
                VisitBinary(exp as BinaryExpression, flag);
                break;

            case ExpressionType.Negate:
            case ExpressionType.NegateChecked:
            case ExpressionType.Not:
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.ArrayLength:
            case ExpressionType.Quote:
            case ExpressionType.TypeAs:
                VisitUnary(exp as UnaryExpression, flag);
                break;

            case ExpressionType.Constant:
                VisitConstant(exp as ConstantExpression, flag);
                break;

            case ExpressionType.Parameter:
                VisitParameter(exp as ParameterExpression, flag);
                break;

            case ExpressionType.Call:
                VisitMethodCall(exp as MethodCallExpression, flag);
                break;

            case ExpressionType.New:
                VisitNew(exp as NewExpression, flag);
                break;

            case ExpressionType.NewArrayInit:
            case ExpressionType.NewArrayBounds:
                VisitNewArray(exp as NewArrayExpression, flag);
                break;

            case ExpressionType.MemberInit:
                VisitMemberInit(exp as MemberInitExpression, flag);
                break;

            case ExpressionType.Conditional:
                VisitConditional(exp as ConditionalExpression);
                break;
            }
        }
 protected virtual void VisitParameter(ParameterExpression parameterExpression, SqlVistorFlag flag)
 {
     // todo
 }
 protected virtual void VisitMemberInit(MemberInitExpression memberInitExpression, SqlVistorFlag flag)
 {
     //  todo
 }
 protected virtual void VisitLambda(LambdaExpression lambda, SqlVistorFlag flag)
 {
     Visit(lambda.Body, flag);
 }