C# SqlServer 未定字段未定条件的组合查询写法


需求分析:

       

        用户提了一种需求是关于数据库组合查询的,之前也封装过组合查询的存储过程,但是之前那个实现起来很简单,写个存储过程,剩下的就是传参了。我今天遇到的这个还不能写成一个存储过程,因为数据库出来SqlServer还要用到一种类似于Access的数据库,不支持存储过程。。为了费一次脑细胞,开发一次逻辑,我决定还是把sql的逻辑写在了D层了。在需求一天变N回的环境下,我还是勇敢而坚强的实现了这个类的封装。

       主要的功能是这样的,如下图有四个查询条件,四个可以任意排列组合,一共有15种组合查询的可能。我的combox下面是checkbox,如下图列出的where后面的值条件也不确定,并且个数不知道。二三十个省,我可以随便选择,年份也是,类型,结果下面也是checkbox复选框的下拉框形式。简单的一句话说,我的组合查询查询字段不定,字段多少不定,条件值不定,条件值多少不定。


C# SqlServer 未定字段未定条件的组合查询写法_第1张图片


C# SqlServer 未定字段未定条件的组合查询写法_第2张图片



实现思路:


       经过讨论决定把各个条件都分别封装给一个list,字段也封装给一个list,我后台获取5个list,再循环list拼接起来字符串放到where in的括号里,做四个判断,把15种情况,分成了四种情况,1,2,3,4个条件的时候是这四种情况。最后通过sqlhelper去查就行了,前台是二哥传给我的5个list,我是封装后台逻辑的,我就简单介绍一下后台的主要代码。


实现代码:


#region GroupQuery() 组合查询:省,年,类型,结果--周洲--2016年3月17日20:14:37     <span style="font-family: Arial, Helvetica, sans-serif;">    </span><pre name="code" class="csharp">        /// <summary>
        /// 组合查询:
        /// </summary>
        /// <param name="ziduan">字段</param>
        /// <param name="sheng">省</param>
        /// <param name="year">年</param>
        /// <param name="protype">类型</param>
        /// <param name="list">结果</param>
        /// <returns>返回List V_ProjectCollectModel </returns>
        public List<V_ProjectCollectModel> GroupQuery(List<string> ziduan, List<string> sheng, List<string> year, List<int> protype, List<string> result)
        {
            #region 取出来四个条件里面的值:省,年,类型,结果,拼接出where in()的内容
            
         
            string shengitem = "'";
            //取出省份,加上“, ”拼接成一个字符串。 
            for (int i = 0; i < sheng.Count; i++)
            {
                if (i==sheng.Count-1)
                {
                    //如果是最后一个,则不需要在结尾加',',需要加上结尾的单引号字符
                    shengitem += sheng[i] + "'";
                }
                else
                {
                    shengitem += sheng[i] + "','";
                }
            }

            string yearitem = "'";
            //取出年份,加上“, ”拼接成一个字符串。 
            for (int i = 0; i < year.Count; i++)
            {
                if (i == year.Count - 1)
                {
                    //如果是最后一个,则不需要在结尾加',',需要加上结尾的单引号字符
                    yearitem += year[i] + "'";
                }
                else
                {
                    yearitem += year[i] + "','";
                }
            }


            string protypeitem = "";
            //取出项目类型,加上“, ”拼接成一个字符串。 
            for (int i = 0; i < protype.Count; i++)
            {
                if (i == protype.Count - 1)
                {
                    //如果是最后一个,则不需要在结尾加',',需要加上结尾的单引号字符
                    protypeitem += protype[i];
                }
                else
                {
                    protypeitem += protype[i] + ",";
                }
            }

            string resultitem = "'";
            //取出评审结果,加上“, ”拼接成一个字符串。 
            for (int i = 0; i < result.Count; i++)
            {
                if (i == result.Count - 1)
                {
                    //如果是最后一个,则不需要在结尾加',',需要加上结尾的单引号字符
                    resultitem += result[i] + "'";
                }
                else
                {
                    resultitem += result[i] + "','";
                }
            }
            #endregion

             //定义list,存放传递过条件的list
            List<string> tiaojian=new List<string>();
            //判断shenglist是否好
            if (sheng.Count>1)
            {
                tiaojian.Add(shengitem);
            }
            if (year.Count>1)
            {
                tiaojian.Add(yearitem);
            }
            if (protype.Count>1)
            {
                tiaojian.Add(protypeitem);
            }
            if (result.Count>1)
            {
                tiaojian.Add(resultitem);
            }

            #region 取出前台传来的ziduanlist的数据
            string ziduanitem = "'";
            //取出查询字段,加上“, ”拼接成一个字符串。 
            for (int i = 0; i < ziduan.Count; i++)
            {
                if (i == ziduan.Count - 1)
                {
                    //如果是最后一个,则不需要在结尾加',',需要加上结尾的单引号字符
                    ziduanitem += ziduan[i] + "'";
                }
                else
                {
                    ziduanitem += ziduan[i] + "','";
                }
            }
            #endregion
            //TODO:如果测试数据代码,写完注释
            string a = resultitem;

            #region 定义查询database需要的参数和返回值
            //定义model是视图,待会放返回值的
            TBToList<V_ProjectCollectModel> dtToList = new TBToList<V_ProjectCollectModel>();
            //定义返回的list
            List<V_ProjectCollectModel> projectcollect;
            //定义dt,返回sqlhelper的查询结果
            DataTable dt = new DataTable();
            //定义sql语句
            string sql = "";
            //定义参数数组
            SqlParameter[] paras= new SqlParameter[]{};
            #endregion

            #region 拼接四种情况的sql语句

            if (ziduan.Count==1)
            {
                string strziduan = ziduan[0];
                string strtiaojian =tiaojian[0];
                sql = "select pname,[year],pjcode,COUNT(pcode)as projectnum,SUM(amount) as totalmoney from V_ProjectCollect  where " + strziduan + " in(" + strtiaojian + ") GROUP BY pname,[year],pjcode";
            }
            else if (ziduan.Count==2)
            {
                string strziduan0 = ziduan[0];
                string strziduan1 = ziduan[1];
                string strtiaojian0 = tiaojian[0];
                string strtiaojian1 = tiaojian[1];
                sql = "select pname,[year],pjcode,COUNT(pcode)as projectnum,SUM(amount) as totalmoney from V_ProjectCollect where " + strziduan0 + " in(" + strtiaojian0 + ")and " + strziduan1 + " in(" + strtiaojian1 + ") GROUP BY pname,[year],pjcode";
               
            }
            else if (ziduan.Count == 3)
            {
                string strziduan0 = ziduan[0];
                string strziduan1 = ziduan[1];
                string strziduan2 = ziduan[2];
                string strtiaojian0 = tiaojian[0];
                string strtiaojian1 = tiaojian[1];
                string strtiaojian2 = tiaojian[2];
                sql = "select pname,[year],pjcode,COUNT(pcode)as projectnum,SUM(amount) as totalmoney from V_ProjectCollect  where " + strziduan0 + " in(" + strtiaojian0 + ")and " + strziduan1 + " in(" + strtiaojian1 + ")and " + strziduan2 + " in(" + strtiaojian2 + ") GROUP BY pname,[year],pjcode";                
            }
            else if (ziduan.Count == 4)
            {
                string strziduan0 = ziduan[0];
                string strziduan1 = ziduan[1];
                string strziduan2 = ziduan[2];
                string strziduan3 = ziduan[3];
                string strtiaojian0 = tiaojian[0];
                string strtiaojian1 = tiaojian[1];
                string strtiaojian2 = tiaojian[2];
                string strtiaojian3 = tiaojian[3];
                sql = "select pname,[year],pjcode,COUNT(pcode)as projectnum,SUM(amount) as totalmoney from V_ProjectCollect  where " + strziduan0 + " in(" + strtiaojian0 + ")and " + strziduan1 + " in(" + strtiaojian1 + ")and " + strziduan2 + " in(" + strtiaojian2 + ")and " + strziduan3 + " in(" + strtiaojian3 + ") GROUP BY pname,[year],pjcode";
                
            }
            #endregion
            //TODO:测试SQL语句的拼接,可以删除 aa
            string aa = sql;

            SqlHelper sqlhelper = new SqlHelper();
            //执行sqlhelper查询
            dt = sqlhelper.ExecuteQuery(sql, CommandType.Text);
            //转换成list
            projectcollect = dtToList.ConvertToModel(dt);
            //返回list数据
            return projectcollect;
        }
        #endregion


 
 


总结:

1.代码要强大到可以应对简单的需求改变,但是无li的需求,要引导用户走到正确的道路上来。

2.学会对自己的代码进行封装,抽象,换思路理解问题,把逻辑想的简单好实现。



你可能感兴趣的:(sql,server,C#,组合查询)