您的位置:首页 > 编程语言 > C#

C#通过传入数组生成Lamda表达式

2016-07-12 11:16 357 查看
后台代码: 

 public class Custom_Expression

    {

        List<Parameter> parameter_list = new List<Parameter>();

        string logical_operator = "";

        /// <summary>

        /// 

        /// </summary>

        /// <param name='left'></param>

        /// <param name='right'></param>

        /// <param name='opername'></param>

        /// <returns>Lambda表达式树</returns>

        public delegate Expression ExpressionEventHandler(Expression left, Expression right, string opername);

        private static BinaryExpression filter = Expression.Equal(Expression.Constant(1), Expression.Constant(1));

        /// <summary>

        /// 自定义Equal方法(允许value为null),value为null 的时候,该查询条件 不会生成

        /// </summary>

        /// <typeparam name='T'>实体数据类型</typeparam>

        /// <param name='columnNames'>以逗号分割的列名称</param>

        /// <param name='values'>这些列对应的值</param>

        /// <returns>返回Lambda表达式,eg:where(Lambda)</returns>

        public Expression<Func<T, bool>> Custom_Equal<T>(string strwhere)

        {

            return Custom_Expression_Common<T>(Equal_result, strwhere);

        }

        /// <summary>

        /// 初始化where 1=1

        /// </summary>

        private void Init()

        {

            filter = Expression.Equal(Expression.Constant(1), Expression.Constant(1));

        }

        /// <summary>

        /// 自定义Contains方法(允许value为null),value为null 的时候,该查询条件 不会生成

        /// </summary>

        /// <typeparam name='T'>实体数据类型</typeparam>

        /// <param name='columnNames'>以逗号分割的列名称</param>

        /// <param name='values'>这些列对应的值</param>

        /// <returns>返回Lambda表达式,eg:where(Lambda)</returns>

        public Expression<Func<T, bool>> Custom_Contain<T>(string strwhere)

        {

            return Custom_Expression_Common<T>(Contains_result, strwhere);

        }

        private Expression Contains_result(Expression left, Expression right, string opername)

        {

            return Expression.Call(left, typeof(string).GetMethod("Contains"), right);

        }

        private Expression Equal_result(Expression left, Expression right, string opername)

        {

            switch(opername)

            {

                case ">=":

                    return Expression.GreaterThanOrEqual(left, right);

                case "<=":

                    return Expression.LessThanOrEqual(left, right);

                case ">":

                    return Expression.GreaterThan(left, right);

                case "<":

                    return Expression.LessThan(left, right);

                case "!=":

                    return Expression.NotEqual(left, right);

                default:

                    return Expression.Equal(left, right);

            }

        }

        /// <summary>

        /// 

        /// </summary>

        /// <typeparam name='T'></typeparam>

        /// <param name='handler'>可以是  Equal、Contains</param>

        /// <param name='columnNames'></param>

        /// <param name='values'></param>

        /// <returns></returns>

        private Expression<Func<T, bool>> Custom_Expression_Common<T>(ExpressionEventHandler handler, string strwhere)

        {

            Init();

            //string strwhere = "is_top=false && status=0 && click > 5";

            parameter_list = BuildExpressionEntitly(strwhere);

            var param = Expression.Parameter(typeof(T));

            for(int i = 0; i<parameter_list.Count; i++)

            {

                if (parameter_list[i].Value == null) continue;

                string columnName = parameter_list[i].ColumnName;

                string operName = parameter_list[i].Operator;

                object value = parameter_list[i].Value;

                Expression left = Expression.Property(param, typeof(T).GetProperty(columnName));

                Expression right = Expression.Constant(ParseValue(value, left.Type.FullName), GetValueType(left.Type.FullName));

                Expression result = handler(left, right, operName);

                if(logical_operator == "&&")

                    filter = Expression.And(filter, result);// where 条件 拼接

                else

                    filter = Expression.Or(filter, result);// where 条件 拼接

                

            }

            return Expression.Lambda<Func<T, bool>>(filter, param);

            //var columns = columnNames.Split(',');

            //var param = Expression.Parameter(typeof(T));

            //for (int i = 0; i < columns.Length; i++)

            //{

            //    if (values[i] == null) continue;

            //    string columnName = columns[i].ToString();

            //    object value = values[i];

            //    Expression left = Expression.Property(param, typeof(T).GetProperty(columnName));

            //    Expression right = Expression.Constant(value, GetValueType(value));

            //    Expression result = handler(left, right, "==");

            //    filter = Expression.And(filter, result);// where 条件 拼接

                

            //}

            //return Expression.Lambda<Func<T, bool>>(filter, param);

        }

        /// <summary>

        /// 构建表达式实体集

        /// </summary>

        /// <param name="strWhere"></param>

        /// <returns></returns>

        private List<Parameter> BuildExpressionEntitly(string strWhere)

        {

            List<Parameter> param_list = new List<Parameter>();

            if(strWhere.IndexOf("&&") > 0)

            {

                logical_operator = "&&";

                strWhere = strWhere.Replace("&&", "&");

                string[] expression = strWhere.Split('&');

                foreach(var exp in expression)

               
4000
{

                    param_list.Add(BuildExpression(exp));

                }

                return param_list;

            }

            else if(strWhere.IndexOf("||") > 0)

            {

                logical_operator = "||";

                strWhere = strWhere.Replace("||", "|");

                string[] expression = strWhere.Split('|');

                foreach (var exp in expression)

                {

                    param_list.Add(BuildExpression(exp));

                }

                return param_list;

            }

            else

            {

                param_list.Add(BuildExpression(strWhere));

                return param_list;

            }

        }

        /// <summary>

        /// 构建单个表达式实体

        /// </summary>

        /// <param name="exp"></param>

        /// <returns></returns>

        private Parameter BuildExpression(string exp)

        {

            object aa = "1233";

            Parameter param = new Parameter();

            if(exp.IndexOf(">=") > 0)

            {

                exp = exp.Replace(">=", "-");

                string[] exp_arr = exp.Split('-');

                param.ColumnName = exp_arr[0].Trim();

                param.Operator = ">=";

                param.Value = exp_arr[1].Trim();

                return param;

            }

            else if (exp.IndexOf("<=") > 0)

            {

                exp = exp.Replace("<=", "-");

                string[] exp_arr = exp.Split('-');

                param.ColumnName = exp_arr[0].Trim();

                param.Operator = "<=";

                param.Value = exp_arr[1].Trim();

                return param;

            }

            else if (exp.IndexOf(">") > 0)

            {

                exp = exp.Replace(">", "-");

                string[] exp_arr = exp.Split('-');

                param.ColumnName = exp_arr[0].Trim();

                param.Operator = ">";

                param.Value = exp_arr[1];

                return param;

            }

            else if (exp.IndexOf("<") > 0)

            {

                exp = exp.Replace("<", "-");

                string[] exp_arr = exp.Split('-');

                param.ColumnName = exp_arr[0].Trim();

                param.Operator = "<";

                param.Value = exp_arr[1];

                return param;

            }

            else if (exp.IndexOf("!=") > 0)

            {

                exp = exp.Replace("!=", "-");

                string[] exp_arr = exp.Split('-');

                param.ColumnName = exp_arr[0].Trim();

                param.Operator = "!=";

                param.Value = exp_arr[1];

                return param;

            }

            else

            {

                exp = exp.Replace("=", "-");

                string[] exp_arr = exp.Split('-');

                param.ColumnName = exp_arr[0].Trim();

                param.Operator = "==";

                param.Value = exp_arr[1].Trim();

                return param;

            }

        }

        /// <summary>

        /// 获取参数的数据类型

        /// </summary>

        /// <param name="value"></param>

        /// <returns></returns>

        private Type GetValueType(string typename)

        {

            if(typename.IndexOf("Int32") >0)

            {

                return typeof(int?);

            }

            else if (typename.IndexOf("Boolean") > 0)

            {

                return typeof(bool?);

            }

            else if(typename.IndexOf("DateTime") > 0)

            {

                return typeof(DateTime?);

            }

            else if(typename.IndexOf("Guid") > 0)

            {

                return typeof(Guid?);

            }

            else

            {

                return typeof(String);

            }

        }

        private object ParseValue(object value, string typename)

        {

            if(typename.IndexOf("Int32") >0)

            {

                return Convert.ToInt32(value);

            }

            else if (typename.IndexOf("Boolean") > 0)

            {

                return Convert.ToBoolean(value);

            }

            else if(typename.IndexOf("DateTime") > 0)

            {

                return Convert.ToDateTime(value);

            }

            else if(typename.IndexOf("Guid") > 0)

            {

                return new Guid(value.ToString());

            }

            else

            {

                return value.ToString();

            }

        }

    }

    public class Parameter

    {

        /// <summary>

        /// 字段名称

        /// </summary>

        public string ColumnName { get; set; }

        /// <summary>

        /// 运算符

        /// </summary>

        public string Operator { get; set; }

        /// <summary>

        /// 字段值

        /// </summary>

        public object Value { get; set; }

    }

调用方法:

   var where = PredicateExtensions.True<T>();

   Expression<Func<T, bool>> is_top =  CE.Custom_Equal<T>("is_top=false && status=0 && click > 5");

   where = where.And(is_top);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Lamda c#