前言
上篇博客我写的是一般只涉及到一张表,并且无条件的分页,语句一般比较简单,但是多张表有条件的分页,确实让我头疼了好久。鉴于上篇博客介绍的方法过程已经很详细,这篇就来把重点内容摘要出来,分享给大家。
多张表有条件真分页
在list.aspx页面中,如果采用一般的分页方法,我们会发现有问题,具体问题就是无“name”字段,问题出在这个地方:
加重颜色的部分,有一个选取“name”字段的代码,这段代码是在页面第一次加载时,通过首页传来的caId,查找出相应的id对应的类别名称,然后显示在页面上,如图,caid=65。
这时候我就犯难了,我在点击了首页的某一个类别之后,能跳转到相应类别下面的所有新闻,但是,当我在点击一个新闻分页的时候,就会抛出错误,“无法找到相应的name字段”。这是因为之前我们用的方法“SelectAllPage”返回的新闻表中,没有“name”这个字段,于是,我就想了几个方法。
方法一
人为的构造“name”字段:我对存储过程做了些修改,用news表以“n.caId=ca.id and n.caId=@caid”的条件内连接category表,使news表中的数据按序号升序排列并将序号生成一个字段“Row”,然后将category表“name”字段中的数据查出来并生成在temptbl表中的“name”字段中。根据字段“Row”来找出每页的起止条数,name字段则是新闻所在类的名称。除了这两个附加的字段之外,news表中所有字段也将作为temptbl表的字段。两张表里的字段共同生成一个“temptbl”表,如下:
with temptbl as (这段存储过程在sql server中执行完美解决了这个问题,返回的表也相当的标准。如图:
select ROW_NUMBER() over(order by n.id desc)as Row,ca.name as name, n.* from news n
inner join category ca on n.caId=ca.id and n.caId=@caid
)
select * from temptbl where Row between @startindex and @endindex
当然,如果对sql内连接语句不是很熟悉的话,也可以用这样的语句:
declare @name char(50)这个就是先将该新闻所对应的“name”字段取出来,然后在temptbl表中生成一个独立的字段,和上述方法原理相同,都是构造“name”字段。其他的任何地方是不需要改变的。
select @name=name from category where id=@caid;
with temptbl as (
select ROW_NUMBER() over(order by id desc)as Row,@name as name,* from news)
select * from temptbl where Row between @startindex and @endindex
然后,我将存储过程应用到了我的系统中,在D层只需要在方法上多加一个参数:
/// <summary>在U层则是给参数赋值和调用方法:
/// 某类别新闻列表分页设计
/// </summary>
/// <param name="startindex">开始条数</param>
/// <param name="endindex">结束条数</param>
/// <returns></returns>
public DataTable SelectCaNewsPage(int startindex, int endindex,string caid)
{
SqlParameter[] paras ={
new SqlParameter("@startindex",startindex),
new SqlParameter("@endindex",endindex),
new SqlParameter("@caid",caid )
};
string sql = "news_SelectCaNewsPage";
DataTable dt = sqlhelper.ExecuteReader(sql, CommandType.StoredProcedure, paras);
return dt;
}
/// <summary>(其他同无条件的分页)
/// 分行显示数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void anp_PageChanged(object sender, EventArgs e)
{
int startindex = anp.StartRecordIndex;
int endindex = anp.EndRecordIndex;
string caid = Request.QueryString["caid"];
DataTable dt = new NewsManager().SelectCaNewsPage(startindex, endindex,caid);
//绑定新闻列表
gvNews.DataSource = dt;
gvNews.DataBind();
}
运行我们的程序,分页成功。
方法二
局部刷新:上面一种方法成功后,我想了一下,为什么它会抛出缺失“name”的错误,我觉得应该是我们在点击页数的时候,刷新的不只是gridview控件,而是整个页面,在这个页面刷新的同时,就会找不到“name”,那我们能不能将刷新区域限制在这个gridview中呢?于是我使用了之前讲过的AJAX的UpdatePanel,将整个gridview包了起来,然后,错误又来了,先别说点不点页数,就连list页面都不能正确显示了,想了想原因,应该是我只让这一部分刷新,在页面重载的时候其他需要刷新的控件得不到数据,从而报错,探究无果之后,果断放弃了这个方法,但这不失为一个好的想法,只不过是技术有限,等我探究出来再分享给大家。
总结
不管是技术,还是思想,如果不去实践,永远不知道自己能收获多少。为未来的自己加油。