C#-ラムダ式がwhere条件付きSQLステートメント2に変換されました

    /// <summary>
    /// 根据Expression表达式生成SQL-Where部分的语句
    /// </summary>
    public class SqlGenerate
    {
        
        ///<summary>
        /// 生成SQL-Where语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public string QueryWhereByLambda<T>(Expression<Func<T, bool>> expression)
        {
            QueryWhereExpressionVisitor expressionVisitor = new QueryWhereExpressionVisitor();
            return expressionVisitor.Extract(expression);
        }
    }
internal delegate object FunctionReturningObject();
/// <summary>
    /// 
    /// </summary>
    internal interface IDMSExpressionModifier
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        Expression Modify(Expression expr);
    }
  /// <summary>
    /// 
    /// </summary>
    internal class LocalDMSExpressionChecker : ExpressionVisitor
    {
        private static readonly LocalDMSExpressionChecker Instance = new LocalDMSExpressionChecker();
        private bool _foundParameter;
        private bool _foundConstant;
        private bool _foundSpecialMethod;
        private string[] specialMethodName = new string[]
		{
			"As",
			"Len",
		};
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="funcReturningObj"></param>
        /// <returns></returns>
        public static bool TryMatchLocalExpression(Expression expr, out FunctionReturningObject funcReturningObj)
        {
            bool result;
            try
            {
                LocalDMSExpressionChecker localExpressionChecker = new LocalDMSExpressionChecker();
                localExpressionChecker.Visit(expr);
                bool flag = localExpressionChecker._foundConstant && !localExpressionChecker._foundParameter && !localExpressionChecker._foundSpecialMethod;
                if (flag)
                {
                    funcReturningObj = LocalDMSExpressionChecker.CompileLocalExpression(expr);
                }
                else
                {
                    funcReturningObj = null;
                }
                result = flag;
            }
            catch (Exception arg)
            {
                Console.WriteLine("TryMatchLocalExpression failed: " + arg);
                throw;
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="constExpr"></param>
        /// <returns></returns>
        public static bool TryMatchLocalExpression(Expression expr, out ConstantExpression constExpr)
        {
            FunctionReturningObject functionReturningObject;
            if (LocalDMSExpressionChecker.TryMatchLocalExpression(expr, out functionReturningObject))
            {
                constExpr = Expression.Constant(functionReturningObject(), expr.Type);
                return true;
            }
            constExpr = null;
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public static FunctionReturningObject CompileLocalExpression(Expression expr)
        {
            Expression body = expr;
            if (expr.Type.IsPrimitive())
                body = Expression.Convert(expr, typeof(object));
            ParameterExpression[] parameters = new ParameterExpression[0];
            LambdaExpression lambdaExpression = Expression.Lambda<FunctionReturningObject>(body, parameters);
            Delegate @delegate = lambdaExpression.Compile();
            return @delegate as FunctionReturningObject;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public static ConstantExpression ConvertConstantExpression(Expression expr)
        {
            FunctionReturningObject functionReturningObject = LocalDMSExpressionChecker.CompileLocalExpression(expr);
            return Expression.Constant(functionReturningObject(), expr.Type);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected override Expression VisitConstant(ConstantExpression c)
        {
            this._foundConstant = true;
            return base.VisitConstant(c);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        protected override Expression VisitParameter(ParameterExpression p)
        {
            this._foundParameter = true;
            return base.VisitParameter(p);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (this.specialMethodName.Contains(m.Method.Name))
            {
                this._foundSpecialMethod = true;
            }
            return base.VisitMethodCall(m);
        }

    }
/// <summary>
    /// 
    /// </summary>
    internal class LocalDMSExpressionModifier : UMS.Framework.Util.ExpressionVisitor, IDMSExpressionModifier
    {
        internal static readonly IDMSExpressionModifier Instance = new LocalDMSExpressionModifier();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public Expression Modify(Expression expr)
        {
            return this.Visit(expr);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        protected override Expression VisitBinary(BinaryExpression b)
        {
            ConstantExpression result;
            if (LocalDMSExpressionChecker.TryMatchLocalExpression(b, out result))
                return result;
            return base.VisitBinary(b);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            ConstantExpression result;
            if (m != null && m.Expression == null)
            {
                result = LocalDMSExpressionChecker.ConvertConstantExpression(m);
                return result;
            }
            if (LocalDMSExpressionChecker.TryMatchLocalExpression(m, out result))
                return result;
            return base.VisitMemberAccess(m);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="na"></param>
        /// <returns></returns>
        protected override Expression VisitNewArray(NewArrayExpression na)
        {
            ConstantExpression result;
            if (LocalDMSExpressionChecker.TryMatchLocalExpression(na, out result))
                return result;
            return base.VisitNewArray(na);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="u"></param>
        /// <returns></returns>
        protected override Expression VisitUnary(UnaryExpression u)
        {
            ConstantExpression result;
            if (LocalDMSExpressionChecker.TryMatchLocalExpression(u, out result))
                return result;
            return base.VisitUnary(u);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            ConstantExpression result;
            if (LocalDMSExpressionChecker.TryMatchLocalExpression(m, out result))
                return result;
            return base.VisitMethodCall(m);
        }
    }
/// <summary>
    ///
    /// </summary>
    internal class LocalExpressionChecker : ExpressionVisitor
    {
        private static readonly LocalExpressionChecker Instance = new LocalExpressionChecker();

        private bool foundParameter;
        private bool foundConstant;
        private bool foundSpecialMethod;
        private string[] specialMethodName = new string[]
		{
			"As",
			"Len",
		};

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="funcReturningObj"></param>
        /// <returns></returns>
        public static bool TryMatchLocalExpression(Expression expr, out FunctionReturningObject funcReturningObj)
        {
            bool result;
            try
            {
                LocalExpressionChecker localExpressionChecker = new LocalExpressionChecker();
                localExpressionChecker.Visit(expr);
                bool flag = localExpressionChecker.foundConstant && !localExpressionChecker.foundParameter && !localExpressionChecker.foundSpecialMethod;
                if (flag)
                {
                    funcReturningObj = LocalExpressionChecker.CompileLocalExpression(expr);
                }
                else
                {
                    funcReturningObj = null;
                }
                result = flag;
            }
            catch (Exception arg)
            {
                Console.WriteLine("TryMatchLocalExpression failed: " + arg);
                throw;
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="constExpr"></param>
        /// <returns></returns>
        public static bool TryMatchLocalExpression(Expression expr, out ConstantExpression constExpr)
        {
            FunctionReturningObject functionReturningObject;
            if (LocalExpressionChecker.TryMatchLocalExpression(expr, out functionReturningObject))
            {
                constExpr = Expression.Constant(functionReturningObject(), expr.Type);
                return true;
            }
            constExpr = null;
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public static FunctionReturningObject CompileLocalExpression(Expression expr)
        {
            Expression body = expr;
            if (TypeTools.IsPrimitive(expr.Type))
                body = Expression.Convert(expr, typeof(object));
            ParameterExpression[] parameters = new ParameterExpression[0];
            LambdaExpression lambdaExpression = Expression.Lambda<FunctionReturningObject>(body, parameters);
            Delegate @delegate = lambdaExpression.Compile();
            return @delegate as FunctionReturningObject;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public static ConstantExpression ConvertConstantExpression(Expression expr)
        {
            FunctionReturningObject functionReturningObject = LocalExpressionChecker.CompileLocalExpression(expr);
            return Expression.Constant(functionReturningObject(), expr.Type);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected override Expression VisitConstant(ConstantExpression c)
        {
            this.foundConstant = true;
            return base.VisitConstant(c);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        protected override Expression VisitParameter(ParameterExpression p)
        {
            this.foundParameter = true;
            return base.VisitParameter(p);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (this.specialMethodName.Contains(m.Method.Name))
                this.foundSpecialMethod = true;
            return base.VisitMethodCall(m);
        }


    }

/// <summary>
    ///  where语句条件生成
    /// </summary>
    internal sealed class QueryWhereExpressionVisitor : ExpressionVisitor
    {
        private StringBuilder stringBuilder = new StringBuilder();
        private bool bConstantStartWith = false;
        private bool bConstantEndWith = false;

        /// <summary>
        /// 查询条件使用属性或者方法或者字段代替常量时使用
        /// </summary>
        private string memberName = string.Empty;

        /// <summary>
        /// 执行表达式解析
        /// </summary>
        /// <param name="exp">表达式</param>
        /// <param name="paramList">参数集合</param>
        /// <returns></returns>
        public string Extract(Expression exp)
        {
            if (exp == null)
                return string.Empty;
            Expression expression = LocalDMSExpressionModifier.Instance.Modify(exp);
            this.Visit(expression);
            return stringBuilder.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected override Expression VisitConstant(ConstantExpression c)
        {
            StringBuilder sbstring = new StringBuilder();
            if (c.Value != null && c.Type.IsArray)
            {
                Array array = c.Value as Array;
                foreach (object current in array)
                {
                    if (current != null)
                        this.AdjustConstant(current, ref sbstring);
                    else
                        sbstring.Append(" null ");
                    sbstring.Append(",");
                }
                this.stringBuilder.Append(sbstring.ToString().Trim(new char[] { ',' }));
            }
            else
            {
                if (c.Value != null)
                {
                    this.AdjustConstant(c.Value, ref sbstring);
                    this.stringBuilder.Append(sbstring.ToString());
                }
                else
                    this.stringBuilder.Append(" null ");
            }
            return base.VisitConstant(c);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (m == null)
                return m;
            string methodName = m.Method.Name;
            MethodInfo method = typeof(QueryWhereExpressionVisitor).GetMethod(methodName);
            if (method != null)
            {
                if (methodName.ToUpper() == "SQLLIKE")
                    this.bConstantStartWith = this.bConstantEndWith = true;
                else if (methodName.ToUpper() == "SQLSTARTWITH")
                    this.bConstantStartWith = true;
                else if (methodName.ToUpper() == "SQLENDWITH")
                    this.bConstantStartWith = true;
                Expression exp = method.Invoke(this, new object[] { m }) as System.Linq.Expressions.Expression;
                this.bConstantStartWith = this.bConstantEndWith = false;
                return exp;
            }
            return base.VisitMethodCall(m);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="na"></param>
        /// <returns></returns>
        protected override Expression VisitNewArray(NewArrayExpression na)
        {
            foreach (Expression current in na.Expressions)
            {
                this.Visit(current);
                this.stringBuilder.Append(" ");
            }
            return na;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="u"></param>
        /// <returns></returns>
        protected override Expression VisitUnary(UnaryExpression u)
        {
            return base.VisitUnary(u);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        protected override Expression VisitBinary(BinaryExpression b)
        {
            this.stringBuilder.Append("(");
            this.Visit(b.Left);
            this.stringBuilder.Append(" " + ExpressionsHelper.FormatOperation(b.NodeType) + " ");
            this.Visit(b.Right);
            this.stringBuilder.Append(")");
            return b;
        }
        /// <summary>
        /// 访问MemberAccess表达式
        /// </summary>
        /// <param name="m">字段或者属性的表达式</param>
        /// <returns></returns>
        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            if (m.Expression is ParameterExpression)
            {
                base.VisitMemberAccess(m);
                //当前为属性名称=>将转换为字段名称
                string columnName = m.Member.Name;
                stringBuilder.Append(columnName);
                return m;
            }
            if (m.Expression is ConstantExpression)
            {
                //属性名
                //暂无支持方法名、字段名
                this.memberName = m.Member.Name;
            }
            return base.VisitMemberAccess(m);
        }
        /// <summary>
        /// 填充具体的值
        /// </summary>
        /// <param name="value">要附加的值</param>
        /// <param name="sbString">要填充到的可变字符串值</param>
        private void AdjustConstant(object value, ref StringBuilder sbString)
        {
            Type type = value.GetType();
            if (type == typeof(string) || type == typeof(bool) || type == typeof(DateTime) || type == typeof(Guid))
            {
                if (bConstantStartWith)
                    value = value + "%";
                if (bConstantEndWith)
                    value = "%" + value;
                if (type != typeof(bool))
                    sbString.AppendFormat("'{0}'", value.ToString().Replace("'", "''"));
                else
                    sbString.AppendFormat("{0}", ((bool)value) ? "1" : "0");
            }
            else
            {
                if (type.IsClass)
                {
                    sbString.AppendFormat("'{0}'", type.GetProperty(this.memberName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).GetValue(value, null));
                    return;
                }
                if (bConstantStartWith)
                    value = value + "%";
                if (bConstantEndWith)
                    value = "%" + value;
                sbString.AppendFormat("'{0}'", value);
            }
        }
        /// <summary>
        /// 处理in关键字
        /// </summary>
        /// <param name="m">表示方法调用</param>
        /// <returns>返回表达式</returns>
        public Expression HandleSqlIn(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" in (");
            if (m.Arguments[1].Type.BaseType == typeof(Array))
            {
                UnaryExpression castMethodCall = Expression.Convert(m.Arguments[1], typeof(Array));
                LambdaExpression exp = Expression.Lambda(castMethodCall);
                var dynamicObject = exp.Compile();
                var obj = dynamicObject.DynamicInvoke() as Array;
                for (int index = 0; index < obj.Length; index++)
                {
                    AdjustConstant(obj.GetValue(index), ref this.stringBuilder);
                    this.stringBuilder.Append(",");
                }
                this.stringBuilder = this.stringBuilder.Remove(this.stringBuilder.Length - 1, 1);
            }
            else
                this.Visit(m.Arguments[1]);
            this.stringBuilder.Append("))");
            return m;
        }
        /// <summary>
        /// 处理not in关键字
        /// </summary>
        /// <param name="m">表示方法调用</param>
        /// <returns>返回表达式</returns>
        public Expression HandleSqlNotIn(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" not in (");
            if (m.Arguments[1].Type.BaseType == typeof(Array))
            {
                UnaryExpression castMethodCall = Expression.Convert(m.Arguments[1], typeof(Array));
                LambdaExpression exp = Expression.Lambda(castMethodCall);
                var dynamicObject = exp.Compile();
                var obj = dynamicObject.DynamicInvoke() as Array;
                for (int index = 0; index < obj.Length; index++)
                {
                    AdjustConstant(obj.GetValue(index), ref this.stringBuilder);
                    this.stringBuilder.Append(",");
                }
                this.stringBuilder = this.stringBuilder.Remove(this.stringBuilder.Length - 1, 1);
            }
            else
                this.Visit(m.Arguments[1]);
            this.stringBuilder.Append("))");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression HandleSqlLike(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" like ");
            this.Visit(m.Arguments[1]);
            this.stringBuilder.Append(")");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression StartWith(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" like ");
            this.Visit(m.Arguments[1]);
            this.stringBuilder.Append(")");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression EndWith(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" like ");
            this.Visit(m.Arguments[1]);
            this.stringBuilder.Append(")");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Equals(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            if (m.Object != null)
                this.Visit(m.Object);
            this.stringBuilder.Append(" = ");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(")");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression SameAS(MethodCallExpression m)
        {
            object value = LocalExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
            this.stringBuilder.Append(" (");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.AppendFormat(" = '{0}'", value);
            this.stringBuilder.Append(")");
            return m;
        }
        /// <summary>
        /// 
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression ToString(MethodCallExpression m)
        {
            this.stringBuilder.Append("'");
            if (m.Object != null)
                this.Visit(m.Object);
            this.stringBuilder.Append("'");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression IsNull(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" IS NULL)");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression IsNotNull(MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" IS NOT NULL)");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression CountAll(MethodCallExpression m)
        {
            this.stringBuilder.Append(" Count(*) ");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Count(MethodCallExpression m)
        {
            this.MethodFunc(m.Method.Name, m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Len(MethodCallExpression m)
        {
            this.MethodFunc(m.Method.Name, m);
            return m;
        }
        /// <summary>
        /// /
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Max(MethodCallExpression m)
        {
            this.MethodFunc(m.Method.Name, m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Min(MethodCallExpression m)
        {
            this.MethodFunc(m.Method.Name, m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Avg(MethodCallExpression m)
        {
            this.MethodFunc(m.Method.Name, m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Sum(MethodCallExpression m)
        {
            this.MethodFunc(m.Method.Name, m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression As(MethodCallExpression m)
        {
            this.Visit(m.Arguments[0]);
            object value = LocalExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
            if (value != null)
            {
                this.stringBuilder.Append(" AS ");
                this.stringBuilder.Append(value);
            }
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression Coalesce(MethodCallExpression m)
        {
            object value = LocalExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
            this.stringBuilder.Append(" coalesce(");
            this.Visit(m.Arguments[0]);
            //this.stringBuilder.Append(",");
            if (m.Arguments[1].GetType() == typeof(string))
                this.stringBuilder.Append(",'" + value + "'");
            else
                this.stringBuilder.Append("," + value);
            this.stringBuilder.Append(")");
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression NewID(MethodCallExpression m)
        {
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="m"></param>
        private void MethodFunc(string methodName, MethodCallExpression m)
        {
            if (methodName.StartsWith("sql", StringComparison.OrdinalIgnoreCase))
                methodName = methodName.Remove(0, 3);
            this.stringBuilder.Append(" " + methodName.ToLower() + "(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(") ");
        }
        public Expression GreaterThan(MethodCallExpression m)
        {
            this.CompareFunc(">", m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression GreaterThanOrEqual(MethodCallExpression m)
        {
            this.CompareFunc(">=", m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression LessThan(MethodCallExpression m)
        {
            this.CompareFunc("<", m);
            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Expression LessThanOrEqual(MethodCallExpression m)
        {
            this.CompareFunc("<=", m);
            return m;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="compareStr"></param>
        /// <param name="m"></param>
        private void CompareFunc(string compareStr, MethodCallExpression m)
        {
            this.stringBuilder.Append("(");
            this.Visit(m.Arguments[0]);
            this.stringBuilder.Append(" " + compareStr + " ");
            this.Visit(m.Arguments[1]);
            this.stringBuilder.Append(")");
        }
    }

/// <summary>
    /// 
    /// </summary>
    internal class RemoveNullDMSExpressionModifier : ExpressionVisitor, IDMSExpressionModifier
    {
        internal static readonly IDMSExpressionModifier Instance = new RemoveNullDMSExpressionModifier();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public Expression Modify(Expression expression)
        {
            return this.Visit(expression);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        protected override Expression VisitBinary(BinaryExpression b)
        {
            Expression expression = this.Visit(b.Left);
            Expression expression2 = this.Visit(b.Right);
            Expression expression3 = this.Visit(b.Conversion);
            if (expression == null || expression2 == null)
            {
                if (b.NodeType == ExpressionType.LessThan
                    || b.NodeType == ExpressionType.LessThanOrEqual
                    || b.NodeType == ExpressionType.GreaterThan
                    || b.NodeType == ExpressionType.GreaterThanOrEqual
                    || b.NodeType == ExpressionType.Equal
                    || b.NodeType == ExpressionType.NotEqual)
                    return null;
                if (expression == null)
                    return expression2;
                if (expression2 == null)
                    return expression;
            }
            if (expression == b.Left && expression2 == b.Right && expression3 == b.Conversion)
                return b;
            if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)
                return Expression.Coalesce(expression, expression2, expression3 as LambdaExpression);
            return Expression.MakeBinary(b.NodeType, expression, expression2, b.IsLiftedToNull, b.Method);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="na"></param>
        /// <returns></returns>
        protected override Expression VisitNewArray(NewArrayExpression na)
        {
            IEnumerable<Expression> enumerable = this.VisitExpressionList(na.Expressions);
            enumerable = from t in enumerable
                         where t != null
                         select t;
            if (enumerable.Count<Expression>() == 0)
                return null;
            if (enumerable == na.Expressions)
                return na;
            if (na.NodeType == ExpressionType.NewArrayInit)
                return Expression.NewArrayInit(na.Type.GetElementType(), enumerable);
            return Expression.NewArrayBounds(na.Type.GetElementType(), enumerable);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            Expression expression = this.Visit(m.Object);
            IEnumerable<Expression> enumerable = this.VisitExpressionList(m.Arguments);
            enumerable =
                from t in enumerable
                where t != null
                select t;
            if (enumerable.Count<Expression>() != m.Arguments.Count)
                return null;
            if (expression != m.Object || enumerable != m.Arguments)
                return Expression.Call(expression, m.Method, enumerable);
            return m;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected override Expression VisitConstant(ConstantExpression c)
        {
            if (c.Value == null)
                return null;
            if (c.Value.GetType().IsArray)
            {
                bool flag = true;
                Array array = c.Value as Array;
                foreach (object current in array)
                {
                    if (current != null)
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)
                    return null;
            }
            return c;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="u"></param>
        /// <returns></returns>
        protected override Expression VisitUnary(UnaryExpression u)
        {
            Expression expression = this.Visit(u.Operand);
            if (expression == null)
                return null;
            if (expression != u.Operand)
                return Expression.MakeUnary(u.NodeType, expression, u.Type, u.Method);
            return u;
        }
    }





おすすめ

転載: blog.csdn.net/fuweiping/article/details/79143940