需求分析:
用户提了一种需求是关于数据库组合查询的,之前也封装过组合查询的存储过程,但是之前那个实现起来很简单,写个存储过程,剩下的就是传参了。我今天遇到的这个还不能写成一个存储过程,因为数据库出来SqlServer还要用到一种类似于Access的数据库,不支持存储过程。。为了费一次脑细胞,开发一次逻辑,我决定还是把sql的逻辑写在了D层了。在需求一天变N回的环境下,我还是勇敢而坚强的实现了这个类的封装。
主要的功能是这样的,如下图有四个查询条件,四个可以任意排列组合,一共有15种组合查询的可能。我的combox下面是checkbox,如下图列出的where后面的值条件也不确定,并且个数不知道。二三十个省,我可以随便选择,年份也是,类型,结果下面也是checkbox复选框的下拉框形式。简单的一句话说,我的组合查询查询字段不定,字段多少不定,条件值不定,条件值多少不定。
实现思路:
经过讨论决定把各个条件都分别封装给一个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.学会对自己的代码进行封装,抽象,换思路理解问题,把逻辑想的简单好实现。