前段时间,公司让我在财务端优化下显示方式,原先的写法在现在看来让人有点想吐槽。以前的设计可能没考虚欠缺,加载方式是一次性加载完,然后在根据当前页分页绑定显示,而更要命的是这个页面展
示的又不是一个表的数据,还有一个关联表,关系是一对多,又得把关联后的字段一并显示,当两张表同样数据过万的时候,问题出现了,页面需要很久才能加载出来,让客户认为我们这个页面是不是有问题。不
得不说,当客户怀疑你软件的功能的时候,那么就该重新思考代码是不是真的有问题了。
以前想优化这个功能,确实是伤神,曾经想到用存储过程,当然用存储过程也能实现,可能是不太熟,总想一下搞定,后来决定弃用了,而自己也比较讨厌逻辑实现需要多次访问数据库(会让代码整理性能变
差),可能是实现功能写代码并不想做的仅仅是这个地方实现的原因,就公开了一个分页的方法(此方法不是原创),传入参数自动实现拼接就能实现获取自己想要的功能。分页总理思路,如有条件需先获取模糊
查询条件,然后获取总页的数据量,在查询那里查出整体数量,把分页查询以及页面展示单独抽出来,这样在选择上一页,下一页,以及跳页时调用这个抽出来的方法,根据当前页就可以了,既提高了性能(不必
每次查总页数),又提高了代码的可读性。分页的实现步骤是
1)定义两个字段变量 当前页(m_currentPage)和一个总共页数m_totalPage,在查主表 记录时初始化这两个变量
2)如有模糊查询,就重构一个获取模糊条件的方法 GetFuzzyCondition(),当然我此处的代码可能对你有点不适应,仅供参考

1 /// <summary> 2 /// 获取模糊查询条件 3 /// </summary> 4 /// <returns>空或者模糊查询条件</returns> 5 private string GetFuzzyCondition() 6 { 7 string strReturn = null; 8 string strQueryText = tb_queryText.Text.Trim(); 9 if (string.IsNullOrEmpty(strQueryText)) 10 { 11 strReturn = ""; 12 } 13 else 14 { 15 strQueryText = "%" + strQueryText + "%"; 16 strReturn = "A.CardID LIKE '" + strQueryText + "'"; 17 strReturn = " And B.LicenseNumber LIKE '" + strQueryText + "'"; 18 } 19 return strReturn; 20 }
3)公开一个 多表关联分页查询 的方法,然后传入参数参数最后查询出结果返回DataTable,以及完成数据展现

1 /// <summary> 2 /// 多表关联分页查询 3 /// </summary> 4 /// <param name="tableName">表名</param> 5 /// <param name="QueryField">查询字段</param> 6 /// <param name="SubqueryField">子表字段</param> 7 /// <param name="orderSql">以哪个字段排序</param> 8 /// <param name="whereSql">查询条件</param> 9 /// <param name="currentPage">当前页</param> 10 /// <param name="pageSize">每页显示大小</param> 11 /// <param name="AssociateQuery">关联表</param> 12 /// <returns>DataTable 数据集</returns> 13 public static DataTable QueryPageData(string tableName, string QueryField, string SubqueryField, string orderSql, string subWhereSql, int currentPage, int pageSize, string AssociateQuery = "", string whereSql = "") 14 { 15 16 if (string.IsNullOrWhiteSpace(SubqueryField)) 17 { 18 SubqueryField = "*"; 19 } 20 if (string.IsNullOrWhiteSpace(QueryField)) 21 { 22 QueryField = "*"; 23 } 24 //优化,因为拼接的语句有条件,而如果传入的没有条件,可能查询不到数据 25 if (string.IsNullOrWhiteSpace(subWhereSql)) 26 { 27 subWhereSql = " 1=1 "; 28 } 29 subWhereSql = subWhereSql.Replace("where", ""); 30 31 int intBeginIndex = (currentPage - 1) * pageSize; 32 int intEndIndex = currentPage * pageSize; 33 34 string sql = "select {0} from("; 35 sql += " select ROW_NUMBER() over(ORDER BY {1}) as 36 RowNumber,{2} from {3} where {4} "; 37 sql += " ) as A {5} where RowNumber>{6} and RowNumber<={7} "; 38 sql = string.Format(sql, QueryField, orderSql, SubqueryField, tableName, subWhereSql, AssociateQuery,intBeginIndex, intEndIndex); 39 sql += whereSql; 40 41 return Common.CommonSQL.ExecSQL(sql); 42 }
定义参数以及方法调用,此处有个小细节,如果你是一对多的,一定要把多的那个字段在最后要查询的结果体现,不然就分页多少条就多少条,例如你要查50条,没加那个多表的字段,你最后的结果也就是50条。

1 string strTableName = "TVIPCard"; 2 string strQueryCondition = GetFuzzyCondition(); 3 string strQueryField = "A.CardID, A.CardType, A.CardTimes, A.IsValid, A.UserName, A.TelephoneNum, A.CompanyName, A.Remark,ISNULL(B.LicenseNumber,'') as LicenseNumber, A.AddTime"; 4 string strSubQueryField = "CardID, CardType, CardTimes, IsValid, UserName, TelephoneNum, CompanyName, Remark, AddTime"; 5 string strOrderBySql = "CardID"; 6 string strAssociateQuery = " left join TVIPCardAndLicNum b on A.CardID = b.CardID "; 7 string strWhereSql = ""; 8 9 DataTable tableRes = Common.CommonSQL.QueryPageData(strTableName, strQueryField, strSubQueryField, strOrderBySql, "", m_currentPage, PageSize, strAssociateQuery, strWhereSql);
查询结果展示,此部分略过,因为我把我怎么展示的写出来,到你那也可能不适应了。当然本文更多的是业务代码,当你代码驾驭能力提高了,建议不要这样写!