protected virtual DataMember AppendMemberByCoalesce(DataMember left, ExpressionType expType, DataMember right)
        {
            var dataMembers = DataMemberUtil.GetKeyMember(left, right);
            var memberKey   = ToParamMember(dataMembers.Item1);
            var memberValue = ToParamMember(dataMembers.Item2);

            AddParam(memberKey, memberValue);
            StringBuilder nameBuilder = new StringBuilder();

            nameBuilder.AppendFormat("ISNULL({0},{1})", memberKey.Name, memberValue.Name);
            return(new DataMember(nameBuilder.ToString(), null, DataMemberType.None));
        }
 /// <summary>
 /// 处理条件方法
 /// </summary>
 /// <param name="conditionMember"></param>
 /// <param name="ifTrueMember"></param>
 /// <param name="ifFalseMember"></param>
 /// <returns></returns>
 protected virtual DataMember ResolveConditionalMethod(DataMember conditionMember, DataMember ifTrueMember, DataMember ifFalseMember)
 {
     if (conditionMember != null)
     {
         StringBuilder nameBuilder = new StringBuilder();
         nameBuilder.Append("(CASE WHEN ");
         if (conditionMember.MemberType == DataMemberType.None)
         {
             nameBuilder.Append(conditionMember?.Name);
         }
         else
         {
             nameBuilder.AppendFormat("{0}=1", conditionMember?.Name);
         }
         nameBuilder.AppendFormat(" THEN {0} ELSE {1})", ifTrueMember?.Name, ifFalseMember?.Name);
         AddParam(conditionMember, ifTrueMember, ifFalseMember);
         return(new DataMember(nameBuilder.ToString(), null, DataMemberType.Key));
     }
     return(null);
 }
        public Tuple <string, List <T> > GetSqlWhere(Expression exp)
        {
            DataMember member = Resolve(exp);

            return(Tuple.Create(member.Name, _paramList));
        }
 /// <summary>
 /// 拼接左边和右边参数的方法
 /// </summary>
 /// <param name="left"></param>
 /// <param name="expType"></param>
 /// <param name="right"></param>
 /// <returns></returns>
 protected virtual DataMember AppendMember(DataMember left, ExpressionType expType, DataMember right)
 {
     if (left == null && right == null)
     {
         return(null);
     }
     if (expType == ExpressionType.Coalesce)
     {
         return(AppendMemberByCoalesce(left, expType, right));
     }
     else
     {
         var dataMembers = DataMemberUtil.GetKeyMember(left, right);
         var memberKey   = ToParamMember(dataMembers.Item1);
         var memberValue = ToParamMember(dataMembers.Item2);
         AddParam(memberKey, memberValue);
         StringBuilder nameBuilder = new StringBuilder();
         nameBuilder.AppendFormat("({0} {1} {2})", memberKey?.Name, ResolveExpressionType(expType), memberValue?.Name);
         return(new DataMember(nameBuilder.ToString(), null, DataMemberType.None));
     }
 }
        public DataMember Resolve(Expression exp)
        {
            DataMember dataMember = null;

            if (exp == null)
            {
                return(dataMember);
            }

            switch (exp.NodeType)
            {
            case ExpressionType.Negate:
            case ExpressionType.NegateChecked:
            case ExpressionType.Not:
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.ArrayLength:
            case ExpressionType.Quote:
            case ExpressionType.TypeAs:
                dataMember = this.VisitUnary((UnaryExpression)exp);
                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:
                dataMember = this.VisitBinary((BinaryExpression)exp);
                break;

            case ExpressionType.TypeIs:
                dataMember = this.VisitTypeIs((TypeBinaryExpression)exp);
                break;

            case ExpressionType.Conditional:
                dataMember = this.VisitConditional((ConditionalExpression)exp);
                break;

            case ExpressionType.Constant:
                dataMember = this.VisitConstant((ConstantExpression)exp);
                break;

            case ExpressionType.Parameter:
                dataMember = this.VisitParameter((ParameterExpression)exp);
                break;

            case ExpressionType.MemberAccess:
                dataMember = VisitMemberAccess((MemberExpression)exp);
                break;

            case ExpressionType.Call:
                dataMember = VisitMethodCall((MethodCallExpression)exp);
                break;

            case ExpressionType.Lambda:
                dataMember = this.VisitLambda((LambdaExpression)exp);
                break;

            case ExpressionType.New:
                dataMember = this.VisitNew((NewExpression)exp);
                break;

            case ExpressionType.NewArrayInit:
            case ExpressionType.NewArrayBounds:
                dataMember = this.VisitNewArray((NewArrayExpression)exp);
                break;

            case ExpressionType.Invoke:
                dataMember = this.VisitInvocation((InvocationExpression)exp);
                break;

            case ExpressionType.MemberInit:
                dataMember = this.VisitMemberInit((MemberInitExpression)exp);
                break;

            case ExpressionType.ListInit:
                dataMember = this.VisitListInit((ListInitExpression)exp);
                break;

            default:
                throw new NotSupportedException(exp.NodeType.ToString());
            }
            return(dataMember);
        }