【asp.net】asp分页(有条件查询,牵系多表查询)<牛腩>
前言
上篇博客我写的是一般只涉及到一张表,并且无条件的分页,语句一般比较简单,但是多张表有条件的分页,确实让我头疼了好久。鉴于上篇博客介绍的方法过程已经很详细,这篇就来把重点内容摘要出来,分享给大家。
多张表有条件真分页
在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 ( 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 server中执行完美解决了这个问题,返回的表也相当的标准。如图:
当然,如果对sql内连接语句不是很熟悉的话,也可以用这样的语句:
declare @name char(50) 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这个就是先将该新闻所对应的“name”字段取出来,然后在temptbl表中生成一个独立的字段,和上述方法原理相同,都是构造“name”字段。其他的任何地方是不需要改变的。
然后,我将存储过程应用到了我的系统中,在D层只需要在方法上多加一个参数:
/// <summary> /// 某类别新闻列表分页设计 /// </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; }在U层则是给参数赋值和调用方法:
/// <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页面都不能正确显示了,想了想原因,应该是我只让这一部分刷新,在页面重载的时候其他需要刷新的控件得不到数据,从而报错,探究无果之后,果断放弃了这个方法,但这不失为一个好的想法,只不过是技术有限,等我探究出来再分享给大家。
总结
不管是技术,还是思想,如果不去实践,永远不知道自己能收获多少。为未来的自己加油。
- 3楼ma157326252613天前 12:08
- 恩,先了解下
- 2楼u0130306014天前 06:38
- 加油,很好的分享,内连接、外连接、交叉连接不太了解可以去看看我的博客,相信你会有更加深刻的理解,践行尝试,你会走的更踏实,加油O(∩_∩)O~
- 1楼happyniceyq4天前 21:39
- 学习就是一个不断总结的过程。