简单多条件动态查询的实现

今天公司有个项目需要到多个条件查询的功能,以前两三个条件的时候就用if去判断,草草了事,由于这次有5-9个条件不等的情况下,总不能都用if吧,虽说能实现,不过这代码看上去也太难看,最重要的是没有重用性,也不方便修改,网上找了下,五花八门的,要费时间去理解它,还不如自己封装下,也便于以后的使用:

我前端用的是BUI来设计的,所以条件的传递方式是get/post,所以这个方法是针对“查询条件来自get/post方式的”,如果是用服务器控件传的,这种方式是不适合的哦

好了,首先,为了方便存储每个字段的键值和比较关系,先建立一个Condition类,方便以后操作,代码如下:

 public class Condition
    {
        //字段名
        public string paramName { get; set; }
        //字段值
        public string paramValue { get; set; }
        //操作符
        public ConditionOperate Operation { get; set; }

        // 查询所用到的运算操作符
        public enum ConditionOperate : byte
        {
            Equal,           // 等于
            NotEqual,      // 不等于
            Like,             // 模糊查询
            Lessthan,      // 小于等于
            GreaterThan,  // 大于等于
            Less,          //小于
            Greater      //大于
        }
    }

接着,创建一个拼接查询条件的类:

  public static class ConditionBuilder
    {
        public static string  getWhere<T>(List<Condition> conditions)
        {
            //获取类型
            Type t = typeof(T);
            //获取类型中的属性集合
            PropertyInfo[] properties = t.GetProperties();
            foreach (PropertyInfo p in properties)
            {
                string colName = p.Name;
                //这里参数是通过url地址栏来(get方式)的,所以用Request.QueryString,如果是post(方式),改做下面的Request.From就好
                for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
                {
                    string value = HttpContext.Current.Request.QueryString[i].ToString();
                    //如果字段存在并且不为空
                    if (colName == HttpContext.Current.Request.QueryString.GetKey(i).ToString() && !string.IsNullOrEmpty(value))
                    {
                        Condition ct = new Condition();
                        ct.paramName = colName;
                        ct.paramValue = value;
                        ct.Operation = Condition.ConditionOperate.Equal;
                        conditions.Add(ct);
                    }
                }

            }
            // 数组元素的顺序应该与ConditionOperate枚举值顺序相同
            string[] operateType = { " = ", " <> ", " Like ", " <= ", " >= ", " < ", " > " };
            StringBuilder strWhere = new StringBuilder();
            strWhere.Append(" 1=1 ");

            foreach (Condition item in conditions)
            {
                int index = (int)item.Operation;

                strWhere.Append(" and " + item.paramName + operateType[index] + "'" + item.paramValue + "'");
            }
  
            return strWhere.ToString();
        }
    }

这里,后台直接调用

        List<Condition> conditions = new List<Condition>();
        string strWhere = ConditionBuilder.getWhere<Sends>(conditions);

当然,有一些特殊字段需要做特殊处理的话,也可以在调用getWhere先处理下。
最后的结果是:

访问http://localhost:14073/Index/GetData?a=a1&b=b1&start=0&limit=10&pageIndex=0&field=SendsID&direction=ASC&Receiver=%E9%83%AD%E4%BC%9F&FromUserName=8&FromSchoolName=87&SmsContent=8&SmsType=1&SendStatus=1&StartTime=&EndTime=&_=1404199763638

得到:1=1 and FromUserName = '8' and FromSchoolName = '87' and SmsType = '1' and SmsContent = '8' and SendStatus = '1' and Receiver = '郭伟'

本人也是菜鸟,此方法只能用来处理普通的查询,对于复杂条件查询的还希望有高手赐教,如果大家有其他好的,也希望能分享下。当然,此方法也不适用于linq和ef,

如果有做过linq和ef动态条件查询的朋友也希望分享下。谢谢!

原文地址:https://www.cnblogs.com/qtqq/p/3818588.html