Asp.net uses the ObjectDataSource control to implement real Ajax pagination in ASP. NET

Source: Internet
Author: User

The ListView control does not have the paging function, but ASP. with the newly added DataPager control in. NET, we can easily set pagination for the data in the ListView. This requires almost no developers to write a line of code and place the ListView control on the page, set the layout and DataSource, add a DataPager control, set its PagedControlID attribute to the ID of the ListView, and set the number of data entries to be displayed on each page in PageSize, then set the pagination style in Fields (of course, you do not need to worry about the style, ASP.. NET will define the paging UI according to the built-in style), run the Web program, you will see a ListView page that supports pagination, the whole process is very simple. In ASP. in NET 3.5, Microsoft separated the data binding control from the paging control, so that users can set pages anywhere on the page and define different paging styles according to their own needs, at the same time, the paging control can control any data binding control, which is specified through the PagedControlID attribute. Basically, for paging operations, developers can do whatever they like. How to Use the ListView control and DataPager control is not the focus of this article. Interested readers can check Microsoft's MSDN. I think it should be much more detailed than I have said.

Let's talk about the principle of data paging. When developing Web applications for data binding pages, we often encounter a large amount of data. To prevent the page from becoming too large to load data slowly, the data to be displayed on a page is displayed by page. When a user accesses a page, the page-based function is used to view the data on different pages. This is a good solution, in addition, almost all program designers and developers will show data on the page by page. This is no problem! The problem lies in the paging method.

In general, the simplest way is to read data on all pages to the cache media at a time (this media is generally the memory of the server), and then display only one page of data at a time. This method is easy to implement, and ASP. in the past, almost all data binding controls that support paging were used in this way, so that many ASP. NET Beginners use this method to develop paging Data Binding pages, and are not aware of any problems. Yes. Generally, the simplest and most effective method used in program development will not cause any problems. Moreover, standard controls provided by Microsoft do this. What are the problems? For some small Web applications, this is indeed no problem, because it involves a small amount of data, even if we read all the data into the memory, it is only a few megabytes at best, A little more than 10 megabytes, dozens of megabytes. If the data is plain text (generally, the data stored in the database is text information), dozens of megabytes of data are already thousands of records, the current hardware conditions on the server are good, and the memory is above the G level. It is basically impossible to process this data. However, if the number of records in a table in the database Reaches hundreds of millions, and some fields store file data (that is, binary data ), in this way, it is not an ideal practice to read all the data into the memory at one time. In this case, you need to use the "real paging" method to read the data.

In most cases, we still need to use the "real paging" method to obtain data. Given the starting position (or index of the page) of each page record, and then given the number of data entries and total number of records displayed per page, we want to retrieve only the data on the current page each time. Each time when a user is paging, some data is taken from the database and bound to the page based on these conditions, which can greatly reduce the overhead of the server and a large amount of data is not a problem. This method seems ideal. However, we will find that even if we use the "real paging" method to retrieve data by page, we will still encounter problems. Imagine that in today's Ajax-like Web world, websites that use Ajax to improve user experience are emerging one after another. If you happen to have a paging Data Binding page that uses Ajax, then the problem will occur. Because the Ajax user experience is partial page refresh, on the page data binding page, When you click the page button, the page will update the page data at a fast speed, this experience is quite good for users, but greedy users may want to try clicking the paging button frequently, or even crazy users click the paging button, at this time, your application may encounter a script error because it needs to frequently retrieve paging data from the database and cannot update the data on the page, the user experience is that the page paging function is abnormal and the program crashes.

The combination of "true paging" and "false paging" can effectively solve the problem mentioned above. I call the first data paging method as "false paging", and the second data paging method as "Real paging ". The combination of the two paging methods means that data on n pages is read to the cache at a time, you can determine whether to directly retrieve data from the cache or load data from the database to the cache based on your needs. After all, loading data from the cache is much more efficient. In this way, when you click the paging button, as long as the data exists in the cache, you can load the data very quickly. If the cache expires or the data you want to obtain exceeds the cache, load the new n-page data from the database to the cache. Of course, you can use the synchronous update cache process in Ajax to restrict the UI operations in this process.

In fact, there are a lot of details involved in paging. It is far from enough to give a detailed explanation of all the issues, here I just want to introduce you to a type. NET Ajax method. To make it easier to use Ajax, I directly used the Ajax controls in the ajaxToolkit package provided by Microsoft in Visual Studio. These controls are generally quite useful, the usage of these controls is not introduced here.

Before writing this article, I also read a lot of materials. In fact, when developing data binding pages, we usually use the "real paging" method to process data by PAGE, ASP. the DataPager control in NET 3.5 is a good control for data paging. Some people put the defect that the data binding control provided by Microsoft does not support data "Real paging" on it, I think this is an grievance against it. DataPager is only responsible for paging operations. Regardless of the data source, it is more important to handle paging UI and interaction with users. So how to handle the data source? How does the data binding control know how many pages my data source has been divided into? What page of data is my current data?

These problems once made me very upset, and I tried to use them. NET PagedDataSource object paging data, but later found that this object also needs to read all the data to the memory at a time to support paging. To put it bluntly, it is also a "false paging" data source object, which is no different from DataGrid and GridView. Remember from. NET 2.0, Microsoft provides a series of data source controls (such as SqlDataSource, XmlDataSource, LinqDataSource, and so on) to simplify data source designation for data binding controls, in fact, I think these controls have no great value in addition to simplifying the code, and sometimes they will damage the structure of the program itself. I have always opposed to using these controls directly on the page (of course, it is very convenient to use these controls in programs used for demonstration ). However, I accidentally saw the ObjectDataSource control in the Visual Studio toolbox while studying Ajax's real paging. At first I thought it should be the base control of those DataSource controls, later, I checked the information to know that this control is the only control in all DataSource controls that supports the "real paging" operation. It can achieve the data paging function by setting a few simple attributes, next I will introduce how to use this control.

This control is easy to use. You only need to configure several attributes.

SelectMethod: Specifies the method name used to obtain paging data. This method is a custom. NET method. You can write it in the CodeBehind code on the page and give the method name to the SelectMethod of the ObjectDataSource control. The ObjectDataSource control automatically executes the method you specified by delegation.

TypeName: Use the full name of the ObjectDataSource control class (including the namespace and class name ). This attribute must be specified. ASP. NET loads corresponding methods and objects through reflection.

DataObjectTypeName: Full name of the data source object type. The biggest highlight of the ObjectDataSource control is that it fully supports object-oriented data operations. In hierarchical application development, the code at the data access layer abstracts the tables in the database into class objects and the fields in the database tables into attributes in the class object, the DataObjectTypeName attribute specifies the Database Class Object.

EnablePaging: to enable the data paging function, set the value of this attribute to True.

MaximumRowsParameterName: The value of this attribute is a parameter name (only a parameter name, rather than the number of data entries displayed on each page), used to indicate the number of data entries to be displayed on each page, the ObjectDataSource control transmits this parameter in the method specified by the SelectMethod Attribute Based on the delegate and runs the code in it. Note that the parameter name must be exactly the same as that in the method specified by the SelectMethod attribute.

StartRowIndexParameterName: This attribute is also a parameter name used to indicate the index of the Start record of each page. The usage is the same as that of MaximumRowsParameterName.

SelectCountMethod: This property is a method signature used to tell the ObjectDataSource control how to know the total number of records in the data source. The ObjectDataSource control also executes this method through delegation, so the method signature must be exactly the same as the attribute value.

Then we place a ListView control (or any other data binding control) on the page, set the value of its performanceid attribute to the ID of ObjectDataSource, and then add a DataPager control, set the value of the PagedControlID attribute to the ID of the ListView.

This is the structure relationship diagram of the three data tables in the data source I obtained. The primary table is the Shoutout table, and one record in Shoutout corresponds to multiple images, which are associated through the BaseComment table. Below I will provide the code for obtaining the stored procedure of Shoutout paging data.

Copy codeThe Code is as follows: <% @ Page Language = "C #" AutoEventWireup = "true" CodeBehind = "AllShoutout. aspx. cs" Inherits = "ShoutoutWallTest. AllShoutout" %>

<% @ Register Assembly = "AjaxControlToolkit, Version = 3.0.208425415, Culture = neutral, PublicKeyToken = 28f01b0e84b6d53e"
Namespace = "AjaxControlToolkit" TagPrefix = "ajaxToolkit" %>

<! DOCTYPE html PUBLIC "-// W3C // dtd xhtml 1.0 Transitional // EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<Html xmlns = "http://www.w3.org/1999/xhtml">
<Head runat = "server">
<Title> Untitled Page </title>
<Link href = "Css/style.css" rel = "stylesheet" type = "text/css"/>
</Head>
<Body>
<Form id = "form1" runat = "server">
<Asp: ScriptManager ID = "ScriptManager1" runat = "server">
</Asp: ScriptManager>
<Div id = "shoutoutall">
<Div style = "float: left;">
<Asp: UpdatePanel ID = "UpdatePanel1" runat = "server" UpdateMode = "Conditional">
<ContentTemplate>
<Asp: ObjectDataSource ID = "objectperformance1" runat = "server" SelectMethod = "LoadShoutouts"
TypeName = "ShoutoutWallTest. AllShoutout" DataObjectTypeName = "Model. Shoutout" EnablePaging = "True"
MaximumRowsParameterName = "maxRows" StartRowIndexParameterName = "startIndex" SelectCountMethod = "CountAll"> </asp: ObjectDataSource>
<Div id = "shoutoutalldescription">
<Asp: ListView ID = "lvShoutout" performanceid = "objectperformance1" runat = "server" ItemPlaceholderID = "layoutTableTemplate"
DataKeyNames = "ID" OnItemDataBound = "lvShoutout_ItemDataBound">
<LayoutTemplate>
<Div id = "layoutTableTemplate" runat = "server">
</Div>
</LayoutTemplate>
<ItemTemplate>
<Div class = "shoutoutallcontent">
<Div class = "shoutoutalltext">
<% # Eval ("Description") %> </div>
<Div>
<! -- Add images here -->
<Asp: ListView ID = "lvImages" runat = "server" ItemPlaceholderID = "layoutImages" DataSource = '<% # Eval ("Images") %>'>
<LayoutTemplate>
<Div id = "layoutImages" runat = "server">
</Div>
</LayoutTemplate>
<ItemTemplate>
<A href = 'thumbnail. aspx? Isthumbnail = false & basecommentid = <% # Eval ("BaseCommentID"). ToString () %> & imagetitle = <% # Eval ("Title") %>'
Target = "_ blank">
& imagetitle = <% # Eval ("Title") %>'
Alt = "" class = "shoutoutimg"/> </a>
</ItemTemplate>
</Asp: ListView>
</Div>
<Div class = "shoutoutallposted">
Posted by: <% # Eval ("PostedByName") %> <% # (DateTime) Eval ("PostedDate"). to1_datestring () %> </div>
<Div class = "shoutoutallfooter">
<Asp: Button ID = "btEdit" CssClass = "shoutoutalllistbutton" OnClick = "btEdit_Click" runat = "server"
Text = "Edit"/>
<Asp: Button ID = "btDel" CssClass = "shoutoutalllistbutton" OnClick = "btDel_Click" runat = "server"
Text = "Delete" OnClientClick = "return confirm ('Are you sure delete it? '); "/>
</Div>
</Div>
</ItemTemplate>
</Asp: ListView>
</Div>
<Div class = "shoutoutallfooter">
<Asp: DataPager ID = "DataPager1" runat = "server" PagedControlID = "lvShoutout" PageSize = "25">
<Fields>
<Asp: NextPreviousPagerField ButtonType = "Image" FirstPageText = "Go to first page" FirstPageImageUrl = "./Images" ShowFirstPageButton = "true" ShowNextPageButton = "false"
ShowPreviousPageButton = "false"/>
<Asp: NumericPagerField NumericButtonCssClass = "shoutoutallnumericpager" ButtonType = "Button" PreviousPageImageUrl = ". /Images/volumes "volumes =" volumes "NextPageText ="> "PreviousPageText =" <"CurrentPageLabelCssClass =" shoutoutallcurrentpager "ButtonCount =" 5 "/>
<Asp: NextPreviousPagerField ButtonType = "Image" LastPageText = "Go to last page" LastPageImageUrl = "./Images" ShowLastPageButton = "true" ShowNextPageButton = "false"
ShowPreviousPageButton = "false"/>
</Fields>
</Asp: DataPager>
</Div>
</ContentTemplate>
</Asp: UpdatePanel>
</Div>
</Div>
</Form>
</Body>
</Html>

I put both the data binding control and the paging control in the UploadPanel control, so that the page will perform the data binding and paging operations without refreshing. A nested ListView is used in the code because a Shoutout record corresponds to multiple image records, combined with the data entity class at the data layer, shoutout class has a property similar to List <Image> Images. Therefore, I directly use this property as the data source of the sublistview control. It is mainly used to display thumbnails in each Shoutout record. This article does not focus on displaying thumbnails on pages. In the code, we have specified a parameter name or method signature for the ObjectDataSource Control for data paging. We need to implement these methods below.

There are only two methods. The LoadShoutouts () method is used to obtain the Shoutout set of the data object, that is, the returned value of the List <Shoutout> type. In fact, this method only needs to execute the Stored Procedure for paging in the database. This stored procedure can return both the dataset and the total number of records. Below I will give the stored procedure. The CountAll () method only returns the total number of records.Copy codeThe Code is as follows: using System;
Using System. Collections;
Using System. Configuration;
Using System. Data;
Using System. Linq;
Using System. Web;
Using System. Web. Security;
Using System. Web. UI;
Using System. Web. UI. HtmlControls;
Using System. Web. UI. WebControls;
Using System. Web. UI. WebControls. WebParts;
Using System. Xml. Linq;
Using System. Collections. Generic;
Using Model;
Using BLL;

Namespace ShoutoutWallTest
{
Public partial class AllShoutout: System. Web. UI. Page
{
Public static List <Shoutout> list = null;
Private static int ItemCount = 0;

Protected void Page_Load (object sender, EventArgs e)
{
}

Public List <Shoutout> LoadShoutouts (int startIndex, int maxRows)
{
Int itemCount;
Int pageIndex = 1;
If (startIndex> 0)
{
PageIndex = (startIndex)/25 + 1;
}
List = ShoutoutBLL. GetShoutouts (13, pageIndex, maxRows, true, out itemCount );
ItemCount = itemCount;
Return list;
}

Public int CountAll ()
{
Return ItemCount;
}

/// <Summary>
/// Refresh data after updating and deleting.
/// </Summary>
Private void RefreshData ()
{
LvShoutout. performanceid = objectperformance1.id;
}
}
}

In my code, each page is required to display 25 pieces of data, ShoutoutBLL. the GetShoutouts () method has five parameters. The first parameter is used to specify the conditions for data retrieval. This is a special case in the program. You do not need to worry about it. The second parameter is the page index, the rule starts from 1. In the method, I convert from startIndex to pageIndex. The third parameter is the number of data entries displayed on each page. The fourth parameter is of the out type, and the total number of records is returned, this method is mainly used to execute the stored procedure of the database. The specific code in the BLL namespace belongs to the code at the business logic layer, which is not provided here, the code in the Model namespace is mainly used to return database entity objects, such as Shoutout And Image objects. In the RefreshData () method, specify a value for the performanceid attribute of the ListView control. In this way, you can rebind the data to refresh the data.
Is the part after the program runs. It can be seen that the page UI has been displayed, and for paging operations, I did not write a line of code, which is completely controlled by DataPager. Because the ListView and DataPager controls are both in the UpdatePanel control, when you click the page button, the page only updates the data in the ListView, but does not refresh the entire page, and the data is obtained from the database page by page, in this way, the "real paging" operation is implemented in Ajax mode. The core control is ObjectDataSource. The following is a stored procedure for obtaining paging data. For your reference, this stored procedure uses a temporary table for paging data.Copy codeThe Code is as follows: set ANSI_NULLS ON
Set QUOTED_IDENTIFIER ON
Go

Alter procedure [dbo]. [GetShoutOuts]
-- Add the parameters for the stored procedure here
(
@ LocationID INT,
@ PageIndex INT, -- start from 1.
@ PageSize INT,
@ Showimages BIT,
@ ItemCount INT Output
)
AS
BEGIN
-- Set nocount on added to prevent extra result sets from
-- Interfering with SELECT statements.
Set nocount on;

Declare @ beginRowNumber bigint, @ endRowNumber bigint
Set @ beginRowNumber = (@ PageIndex-1) * @ PageSize + 1;
Set @ endRowNumber = @ PageIndex * @ PageSize;

WITH TempPagingRecord
(
SELECT ROW_NUMBER () OVER (order by PostedDate DESC) AS RecordNumber, SO. id as ShoutOutID, BC. [Description], BC. postedByName, BC. postedDate, null as ImageTitle, null as ImageBlob, null as Type, BC. id as BaseCommentID, BC. displayUserName,
BC. IsVisible, SO. policytoshoutoutuser, SO. ShoutOutToUserAlias
FROM dbo. ShoutOut as SO
JOIN dbo. BaseComment as bc on bc. ID = SO. BaseCommentID
Where so. LocationID = @ LocationID
And bc. IsVisible = 1
)
SELECT RecordNumber,
ShoutOutID,
Description,
PostedByName,
PostedDate,
ImageTitle,
ImageBlob,
BaseCommentID,
DisplayUserName,
IsVisible,
NotifyToShoutOutUser,
ShoutOutToUserAlias
INTO # tempTable
FROM TempPagingRecord
Where RecordNumber between @ beginRowNumber and @ endRowNumber

-- Insert statements for procedure here
IF (@ showimages = 1)
Begin
Select RecordNumber,
ShoutOutID,
Description,
PostedByName,
PostedDate,
IM. ImageTitle,
IM. ImageBlob,
IM. Type,
T. BaseCommentID,
DisplayUserName,
IsVisible,
NotifyToShoutOutUser,
ShoutOutToUserAlias from # tempTable T
Left join dbo. Image im on im. BaseCommentID = T. BaseCommentID
Order by PostedDate DESC
End
ELSE
Begin
SELECT * FROM # tempTable
Order by PostedDate DESC
End

SELECT @ ItemCount = Count (*)
FROM Shoutout as SO
JOIN dbo. BaseComment as bc on bc. ID = SO. BaseCommentID
Where so. LocationID = @ LocationID
And bc. IsVisible = 1
END

I personally think that the ObjectDataSource control is a relatively intelligent control. It automatically executes the paging Code provided by the user through function delegation to complete the "real paging" operation of the database, saving a lot of trouble in the development process, it is necessary to study it carefully.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.