手机版

asp.net使用对象数据源控件在ASP .网中实现埃阿斯真分页

时间:2021-10-25 来源:互联网 编辑:宝哥软件园 浏览:

ListView控件本身没有分页功能,但是借助ASP.NET新增加的DataPager控件,我们可以非常方便地为ListView中的数据设置分页,这几乎不需要开发人员写一行代码,将ListView控件放在页面上,设置好布局和数据源,然后再添加一个DataPager控件。将其PagedControlID属性设置为ListView的ID,在PageSize中设置每页要显示的数据数量,然后在Fields中设置分页样式(当然可以完全忽略样式,ASP.NET会根据内置样式定义分页UI),运行Web程序,会看到一个支持分页的ListView页面。整个过程非常简单。在ASP.NET 3.5中,微软将数据绑定控件和分页控件分开,这样用户就可以在页面的任何地方设置分页,并根据自己的需要定义各种分页样式。同时,分页控件可以控制任何数据绑定控件,并且它们是由PagedControlID属性指定的。基本上,对于分页操作,开发人员可以为所欲为。如何使用ListView控件和DataPager控件不是本文的重点。感兴趣的读者可以查看微软的MSDN。我觉得应该比我说的详细很多。先说说数据分页的原理。当我们开发带有数据绑定页面的Web应用程序时,经常会遇到大量的数据。为了防止页面变得太大和加载数据太慢,每个人都会通过分页来完成要在一个页面上显示的数据。当用户访问页面时,可以通过分页功能查看不同页面的数据,这是一个非常好的解决方案。而且几乎所有的程序员和开发人员都会不约而同的通过分页的方式显示页面上的数据,这是没有问题的!问题出在分页方式上。一般来说,最简单的方法是一次将所有页面的数据读入缓存介质(这个介质通常是服务器的内存),然后一次只显示一页数据。这种方式很容易实现,在ASP.NET之前几乎所有支持分页的数据绑定控件都使用这种方式,所以很多ASP.NET的初学者使用这种方式开发分页数据绑定页面,并没有注意到任何问题。是的,程序开发中使用的最简单、最有效的方法一般不会造成任何问题。此外,微软提供的标准控件都是这样做的。有什么问题?对于一些小型Web应用程序来说,这真的没有问题,因为涉及的数据量相对较小。即使我们把所有的数据都读入内存,最多也就几兆,十几兆,几十兆。如果所有这些数据都是纯文本(一般来说,数据库中存储的所有数据都是文本信息),那么几十兆字节的数据就已经记录成千上万了。现在服务器的硬件条件比较好,内存在G级以上,处理这个数据完全没有问题。但是,如果数据库中的一个表中有上亿条记录,并且有些字段存储文件数据(即二进制数据),那么一次将所有数据读入内存并不是一个理想的方法。此时,需要使用“真分页”来读取数据。在大多数情况下,我们仍然需要使用“真正的分页”来获取数据。给定每页记录的起始位置(或页面的索引),给定每页显示的数据数量和记录总数,我们希望每次只得到当前页面的数据。用户每次分页,根据这些条件,从数据库中取出一部分数据绑定到页面上,可以大大降低服务器的开销,而且无论数据有多大,都不是问题。这个方法似乎很理想。但是,结合用户的需求,我们会发现,即使我们使用“真分页”的方法通过分页来获取数据,仍然会遇到问题。

想象一下,在当今Ajax盛行的Web世界中,有很多网站使用Ajax来改善用户体验。如果您碰巧有一个由Ajax提供的分页数据绑定页面,就会出现这个问题。由于Ajax的用户体验效果是页面的部分刷新,在分页数据绑定页面中,用户点击分页按钮后页面会以更快的速度更新分页数据,这对用户来说是相当不错的,但是贪婪的用户可能会想尝试频繁点击分页按钮,甚至疯狂的用户可能会疯狂点击分页按钮。此时,您的应用程序出现脚本错误,因为它需要非常频繁地从数据库中获取分页数据,所以更新页面上的数据已经太晚了,用户的最终体验是页面的分页功能不可用。“真寻呼”和“假寻呼”相结合可以有效解决上述问题。我把上面提到的第一种数据分页方法叫做“假分页”,第二种数据分页方法叫做“真分页”。这两种分页方式的结合,是指一次将N页数据读入缓存,在分页时根据需要判断是直接从缓存获取数据,还是将数据库中的数据重载到缓存中。毕竟,从缓存中加载数据要高效得多。这样,每次用户单击分页按钮时,只要数据存在于缓存中,就可以以非常快的速度加载数据。如果缓存过期或用户要获取的数据超过缓存,新的N页数据将从数据库重新加载到缓存中。当然,在更新缓存的过程中,可以在Ajax中同步使用,从而限制用户在这个过程中的UI操作。其实分页涉及很多细节。如果要详细描述和澄清所有这些问题,仅靠本文的几句话恐怕远远不够。在这里,我只想介绍一种在ASP.NET Ajax模式下进行真正分页编程的方法。为了更简单地使用Ajax,我在Visual Studio中直接使用微软提供的ajaxToolkit包中的Ajax控件。总的来说,这些控件都挺好用的,这里就不介绍这些控件的用法了。在写这篇文章之前,我也查阅了很多资料。事实上,当我们开发数据绑定页面时,我们通常使用“真正分页”的方法来分页数据。ASP.NET 3.5中的DataPager控件是一个很好的数据分页控件。有人将其归咎于微软提供的数据绑定控件不支持数据“真分页”的缺陷,我认为这是一个错误。DataPager只负责分页操作,它不关心数据源,它更重要的工作是如何处理分页UI和与用户的交互。那么,数据源呢?数据绑定控件如何知道我的数据源分为多少页,以及我当前正在获取哪一页数据?这些问题曾经困扰过我。我试图在中使用PagedDataSource对象。NET来分页数据,但后来发现这个对象还需要一次将所有数据读入内存才能支持分页。说白了,它也是一个“假分页”的数据源对象,和DataGrid、GridView没什么区别。我记得从那以后。NET 2.0,微软提供了一系列数据源控件(如SqlDataSource、XmlDataSource、LinqDataSource等。)来简化数据绑定控件的数据源指定。事实上,我认为这些控件除了简化代码之外没有太大的价值,有时它们会破坏程序本身的结构。我总是反对直接在页面上使用这些控件(当然,在一些演示程序中使用这些控件是非常方便的)。

然而,在研究Ajax真正的分页时,我意外地在Visual Studio工具箱中看到了ObjectDataSource控件。起初,我只是认为它应该是那些数据源控件的基础控件。后来,通过查找数据,我发现这个控件是所有数据源控件中唯一支持“真正分页”操作的控件。它可以通过设置几个简单的属性来实现数据分页的功能。现在我将介绍如何使用这个控件。这个控件的使用非常简单,我们只需要配置几个属性。SelectMethod:指定用于获取分页数据的方法的名称。这个方法是自定义的。NET方法。您可以将其写入页面的代码隐藏代码中,并将方法的名称赋予ObjectDataSource控件的SelectMethod。ObjectDataSource控件将自动执行您通过委托方式指定的方法。TypeName:使用ObjectDataSource控件的类的全名(包括命名空间和类名)。此属性必须指定ASP.NET将通过反射加载相应的方法和对象。DataObjectTypeName:数据源对象类型的全名。ObjectDataSource控件的亮点在于它完全支持面向对象的数据操作。在分层应用的开发中,数据访问层的代码将数据库中的表抽象为类对象,将数据库表中的字段抽象为类对象中的属性。DataObjectTypeName的属性是数据库类对象。EnablePaging:如果要打开数据分页,需要将该属性的值设置为True。MaximumRowsParameterName:这个属性的值是一个参数名(只是一个参数名,而不是每页要显示的数据个数),表示每页要显示的数据个数。ObjectDataSource控件在由前面的SelectMethod属性指定的方法中传递此参数,并根据委托执行其中的代码。请注意,此参数的名称必须与SelectMethod属性指定的方法中的参数名称完全相同。StartRowIndexParameterName:这个属性也是一个参数名,用来表示每页起始记录的索引。用法与MaximumRowsParameterName相同。SelectCountMethod:这个属性是一个方法的签名,用来告诉ObjectDataSource控件如何知道数据源中的记录总数。ObjectDataSource控件也通过委托执行此方法,因此方法的签名必须与属性值完全相同。然后,我们在页面上放置一个ListView控件(或任何其他数据绑定控件),并将其DataSourceID属性的值设置为ObjectDataSource的ID。然后,我们添加一个DataPager控件,并将PagedControlID属性的值设置为ListView的ID。tablerelations

这是我所取的数据源中的三张数据表的结构关系图,其中主表是大喊表大声喊出来中的一条记录对应着多个图像,它们通过基本注释表进行关联。在下面我会给出如果获取大喊分页数据的存储过程的代码。复制代码代码如下: %@页面语言=' c# ' AutoEventWireup=' true '之前的代码=' all shoutout。aspx。cs ' Inherits=' shoutwalltest .all shout " % @ Register Assembly=" AJaxcontroltoolkit,Version=3.0.20820.415,Culture=neutral,公钥标记=28f 01 b 0 e 84 b 6d 53 e " Namespace=" AJaxcontroltoolkit "标记前缀="AJaxtoolkit"%!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN ' ' http://www .w3。org/TR/XHTML L1/DTD/XHTML L1-过渡。DTD ' html xmlns=' http://www .w3。org/1999/XHTML ' head runat=' server ' title无标题Page/title link href=' Css/style。CSS“rel=”样式表type=' text/Css '/head body form idasp : updatepanel ID=' updatepanel 1 ' runat=' server ' UpdateMode=' Conditional '内容模板asp:对象数据源ID=' object data source 1 ' runat=' server ' select method=' loadshouttowners ' TypeName=' shooutwalltest .所有“大喊”数据对象类型名称=“模型.shout ' EnablePaging=' True ' MaximumRowsParameterName=' maxRows ' startrownindexparametername=' startIndex ' select count method=' count all '/ASP : object data source div ID=' shoutal Description ' ASP : listview ID=' lvShoutout ' data source ID=' object data source 1 ' runat=' server ' itemplacholdrid=' layout tabletemplate ' DataKeyNames=' ID ' ontinedata bound=' lvShoutout tout _ item data bound '在此添加图像-asp:列表视图ID=' lvImages ' runat=server ' itemlplaceholdrid=' layoutImages '数据源=' % # Eval(' Images ')% ' LayoutTemplate div ID=' layoutImages ' runat=' server '/div/LayoutTemplate项模板a href='缩略图。 aspx?is thumbnail=false基本注释tid=% # Eval('基本注释tid ').ToString()% image Title=% # Eval(' Title ')% ' target=' _ blank ' img src='缩略图。aspx?基本注释tid=% # Eval('基本注释tid ').ToString()% image Title=% # Eval(' Title ')% ' alt=' shoutoutimg '/a/item template/ASP : listview/div class=' shoutoutall post '由:% # Eval(' posteddyname ')% % #((DateTime)Eval(' PostedDate ')发布)。ToShortDateString()%/div class=' shoutall footer ' asp:按钮ID=' btEdit ' CSS类=' shoutall list button ' OnClick=' btEdit _ Click ' runat=' server ' Text=' Edit '/asp3360按钮ID=' btDel ' CSS类=' shoutall list button ' OnClick=' btDel _ Click ' runat=' server ' Text=' Delete ' OnClientClick=' return confirm('确定要删除吗?');//div/div/item template/ASP : listview/div class=' shoutaellfooter ' ASP 3360 data pager ID=' data pager 1 ' runat=' server '页控件solid=' lvShoutout '页大小=' 25 '字段ASP : extpreviouspagerfield ButtonType=' Image '第一页文本='转到第一页FirstPageImageUrl=' ./Images/ShoutOut _ view _ all _ left。gif ' show first page Button=' true ' ShowNextPageButton=' false ' ShowPreviousPageButton=' false '/ASP : numericpagerfield numericbuttoncsclass=' shoutt all numericpager ' Button type=' Button ' PreviousPageImageUrl=' ./Images/ShoutOut _ view _ all _ left。gif ' next previousbuttoncsclass=' shoutoutall next prepager '下一页text=' PreviousPageText=' currentpagelabelcslass=' shoutoutall currentpager '按钮计数=' 5 '/ASP : extpreviouspagefield按钮类型=' Image ' LastPageText='转到最后一页LastPageImageUrl=' ./Images/shoutot _ view all _ right。gif ' ShowLastPageButton=' true ' ShowNextPageButton=' false ' ShowPreviousPageButton=' false '/Fields/asp: data pager/div/内容模板/asp: updatepanel/div/div/表单/正文/html我把数据绑定控件和分页控件都放在上传面板控件中,这样页面就会在不刷新的情况下执行数据绑定和分页操作。

代码中使用了嵌套的ListView,因为一个“大喊”记录将对应多个图像记录。结合数据层的数据实体类,在Shoutout类中会有一个类似于ListImage Images的属性,所以我直接用这个属性作为ListView控件的数据源,主要用来显示每个Shoutout记录中的缩略图。如何在页面上显示缩略图不是本文的重点,这里就不做介绍了。在代码中,我们已经为ObjectDataSource控件分配了用于数据分页的参数名称或方法签名,我们需要在下面实现这些方法。只有两种方法,LoadShoutouts()方法用来获取数据对象的集合Shoutout,也就是ListShoutout类型的返回值。实际上,这个方法只需要在数据库中执行用于分页的存储过程,并且这个存储过程可以同时返回数据集合和记录总数。我将在下面给出这个存储过程。CountAll()方法只返回记录的总数。复制代码如下:使用System使用系统。收藏品;使用系统。配置;使用系统。数据;使用系统。Linq使用系统。Web使用系统。网络安全;使用系统。Web . UI使用系统。Web . UI.HtmlControls使用系统。网络控件;使用系统。网页组件;使用系统。Xml . Linq使用系统。集合。通用;使用模型;使用BLL;命名空间ShoutoutWallTest { public分部类AllShoutout : System。web . ui . page { public static ListShoutout list=null;私有静态int ItemCount=0;受保护的void Page_Load(对象发送方,event args e){ } public ListShoutout loadshoutource(int startIndex,int maxRows){ int itemCount;int page index=1;if(startIndex 0){ page index=(startIndex)/25 1;} list=ShoutoutBLL。getshouteukers(13,pageIndex,maxRows,true,out item count);ItemCount=itemCount退货清单;} public int CountAll(){ return ItemCount;} ///汇总///更新删除后刷新数据。////summary private void refresh data(){ lvshoutot。数据源ID=对象数据源1。身份证;}}}我的代码要求每页显示25条数据。大喊大叫。getshou师爷()方法有5个参数。第一个参数用于指定检索数据的条件。这是节目中的特例,读者不必在意。第二个参数是页面的索引,规定从1开始,我从startIndex转换为pageIndex在方法中;第三个参数是每页显示的数据数量。第四个参数是out类型,它返回记录的总数。这个方法主要是对应执行数据库的存储过程。具体的代码在BLL命名空间中,属于业务逻辑层的代码,这里就不给出了。模型命名空间中的代码主要用于返回数据库实体对象,如“大喊”和“图像”对象。在RefreshData()方法中,会重新分配ListView控件的DataSourceID属性的值,这样就可以重新绑定数据,达到刷新数据的效果。allshoutout1

上图是程序运行后的部分截图,可以看出分页用户界面已经显示出来了,而且对于分页操作,我没有写一行代码,这个完全由分页自己来控制。由于列表视图和分页控件都位于更新区域控件中,当用户点击分页按钮时页面只是更新了列表视图中的数据而没有刷新整个页面,并且数据是逐页从数据库中得到的,这样便实现了在埃阿斯方式下的"真分页"操作。核心控件是对象数据源。下面是我用于获得分页数据的存储过程,读者可以借鉴一下,这个存储过程采用了临时表的方式进行数据分页。复制代码代码如下:设置ANSI_NULLS开,设置引号_标识符开,开始更改程序[dbo].[getshou师爷] -在此添加存储过程的参数(@LocationID INT,@PageIndex INT,-从一开始@PageSize INT,@showimages BIT,@ ItemCount INT)输出为BEGIN-SET NOCOUNT ON被添加,以防止额外的结果集-干扰挑选语句。设置无计数开启;声明@ beginRowNumber bigint,@ endRowNumber bigint set @ BeginLownNumber=(@ PageIndex-1)* @ PageSize 1;设置@ end row number=@ page index * @ page size;以临时页码记录为(选择行号()结束(按表名邮政编码排序)作为记录号,所以。身份证为大声喊出来,公元前。【描述】,公元前。公元前波斯特德邦发布日期,空为ImageTitle,空为ImageBlob,空为类型,公元前.标识为基本注释,公元前。显示用户名公元前200年.可见,所以。通知用户。来自数据库所有者的大喊大叫.大声喊出来,加入dbo .公元前评论为公元前身份证=SO .基本注释地点LocationID [emailprotected]和公元前300年.IsVisible=1 ) SELECT RecordNumber,ShoutOutID,Description,postedname,postdated,ImageTitle,ImageBlob,BaseCommentID,DisplayUserName,IsVisible,NotifyToShoutOutUser,shouttouserias INTO # tempTable FROM temp pagin记录其中记录号在@ beginRowNumber和@ endRowNumber之间-在此处插入过程的语句中频(@showimages=1)开始选择记录号,大声喊出来,描述,发布数据名,发布日期,即时消息.图片标题,即时消息ImageBlob,IM .类型,T.BaseCommentID,DisplayUserName,IsVisible,NotifyToShoutOutUser,ShoutOutToUserAlias来自#临时表T左连接dbo .图像即时消息打开即时消息基础评论按邮政编码排序表名结束其他开始从#临时表中选择*按邮政编码排序表名结束选择@项目计数=从“大喊”中计数(*)作为SO JOIN dbo .公元前评论为公元前身份证=SO .基本注释地点LocationID [emailprotected]和公元前300年.IsVisible=1 END个人觉得对象数据源控件是一个比较智能化的控件,它通过函数委托的方式自动执行用户提供的分页代码来完成数据库的"真分页"操作,省去了开发过程中的很多麻烦,还是很有必要去认真研究一下的。

版权声明:asp.net使用对象数据源控件在ASP .网中实现埃阿斯真分页是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。