Sunday, April 12, 2015

ASP.NET ListView Custom Paging with DataPager

When displaying large amounts of data it's often best to only display a portion of the data, allowing the user to step through the data ten or so records at a time. While default paging was easy to implement, it carried with it a performance cost since all records to be paged through were being returned from the database.Custom paging solved this performance issue by requiring the page developer to tell the ListView exactly how many total records were being paged through as well as returning the precise subset of records to display on the page. The following example use ObjectDataSource for DAL and Microsoft.Practices.EnterpriseLibrary.Data.dll (download here) to shorten code.
ListView Custom Paging
Copy the following code to <head> tag.
<head runat="server">
    <title>ListView Test</title>
    <style type="text/css">
        .imgborder {
            border-color: #CCC;
            border-width: thin;
            border-style: solid;
            margin: 5px;
            padding: 5px;
        }
    </style>
</head>  
Here is server controls and copy to <form> tag.
<asp:ListView ID="ListView1" runat="server" GroupItemCount="4" GroupPlaceholderID="groupPlaceHolder1"
      ItemPlaceholderID="itemPlaceHolder1" DataSourceID="ObjectDataSource1" OnPagePropertiesChanging="ListView1_PagePropertiesChanging">
      <LayoutTemplate>
          <table>
               <asp:PlaceHolder runat="server" ID="groupPlaceHolder1"></asp:PlaceHolder>
          </table>
      </LayoutTemplate>
      <GroupTemplate>
          <tr>
              <asp:PlaceHolder runat="server" ID="itemPlaceHolder1"></asp:PlaceHolder>
          </tr>
      </GroupTemplate>
      <ItemTemplate>
           <td class="imgborder">
               <asp:Label ID="lblCustomerID" runat="server" Text='<%#Eval("CustomerID") %>' /></br>
               <asp:Label ID="lblCompanyName" runat="server" Text='<%#Eval("CompanyName") %>' /><br>
               <asp:Label ID="lblContactName" runat="server" Text='<%#Eval("ContactName") %>' />
           </td>
      </ItemTemplate>
      <EmptyDataTemplate>
          There is no data.
      </EmptyDataTemplate>
 </asp:ListView>
 <asp:DataPager ID="DataPager1" runat="server" PageSize="8" PagedControlID="ListView1">
      <Fields>
           <asp:NumericPagerField />
      </Fields>
 </asp:DataPager>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GridDataPage"
    TypeName="DAL" SelectCountMethod="DataRowCount" 
    SortParameterName="SortExpression" EnablePaging="True">
    <SelectParameters>
        <asp:Parameter Name="maximumRows" Type="Int32" />
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="SortExpression" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>
In code-behind, "ListView1_PagePropertiesChanging" event is as below:
protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
    DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
    ListView1.DataBind();
}
Here is the connection string in web.config and it use sample "Northwind" db (download here) and "Customers" table.
<connectionStrings>
    <add name="sqlConn" providerName="System.Data.SqlClient"  connectionString="Server='.\SQLEXPRESS';uid='xxxxxx';pwd='xxxxxxxx';Database='Northwind';Pooling=False;"/>
</connectionStrings>
Here is the underlying DAL class for ObjectDataSource.
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
public class DAL
{
    // Methods
    private static Database getDatabase()
    {
        Database database = null;
        try
        {
            database = DatabaseFactory.CreateDatabase("sqlConn");
        }
        catch (Exception ex)
        {
            //handle exception here.
        }
        return database;
    }
    public static DataSet GridDataPage(int maximumRows, int startRowIndex, string SortExpression)
    {
        DataSet ds = new DataSet();
        if (startRowIndex >= maximumRows)
        {
            startRowIndex++;
        }
        try
        {
            ds = getGridData(maximumRows, startRowIndex, SortExpression);
            if (ds != null && ds.Tables[0].Rows.Count > 0)
            {
                startRowIndex = (startRowIndex > 0) ? startRowIndex : 1;
                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    ds.Tables[0].Rows[i][0] = Convert.ToString((int)(i + startRowIndex));
                }
                HttpContext.Current.Items["rowCount"] = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
                return ds;
            }
            HttpContext.Current.Items["rowCount"] = 0;
        }
        catch (Exception ex)
        {
            //handle exception here.
        }
        return ds;
    }
    public static DataSet getGridData(int maximumRows, int startRowIndex, string SortExpression)
    {
        DataSet ds = new DataSet();
        try
        {
            ds = getDatabase().ExecuteDataSet("GetCustomers", new object[] { maximumRows, startRowIndex, SortExpression });
        }
        catch (Exception ex)
        {
            ds = null;
            //handle exception here.
        }
        return ds;
    }
    public static int DataRowCount(int maximumRows, int startRowIndex, string SortExpression)
    {
        return (int)HttpContext.Current.Items["rowCount"];
    }
}
Here is transact-sql (store procedure).
USE [Northwind]
GO
ALTER PROCEDURE [dbo].[GetCustomers]
    @pageSize INT = NULL,
    @pageStart INT = NULL,
    @orderBy nvarchar(200) = NULL
AS
BEGIN

DECLARE @sqlPopulate VARCHAR(2000)
IF @pageSize IS NULL or @pageSize = 0
    SET @pageSize = 10;
IF @pageStart IS NULL
    SET @pageStart = 0;
IF @orderBy IS NULL OR @orderBy = '' 
    SET @orderBy = 'CustomerID DESC';
IF @pageStart = 0
BEGIN
    SET @sqlPopulate = 'SELECT '' '' AS No, CustomerID, CompanyName, ContactName, ContactTitle ' +
        + ' FROM dbo.Customers WHERE CustomerID IN '+
        '(SELECT top '+ CAST(@pageSize AS VARCHAR(10)) +' CustomerID FROM dbo.Customers ';

    SET @sqlPopulate = @sqlPopulate + ' ORDER BY ' + @orderBy +
        ') ORDER BY ' + @orderBy;
END
ELSE
BEGIN
    SET @sqlPopulate = 'SELECT '' '' AS No, CustomerID, CompanyName, ContactName, ContactTitle ' +
        ' FROM Customers WHERE CustomerID IN '+
        '(SELECT top '+ CAST(@pageSize AS VARCHAR(10)) + ' CustomerID FROM Customers WHERE CustomerID NOT IN '+
            '(SELECT top '+ CAST((@pageStart-1) AS VARCHAR(10)) +' CustomerID FROM Customers ';

    SET @sqlPopulate = @sqlPopulate + ' ORDER BY ' + @orderBy +
            ') ORDER BY ' + @orderBy + ') ORDER BY ' + @orderBy;
END
EXEC(@sqlPopulate)

SET @sqlPopulate = '';
SET @sqlPopulate = 'SELECT COUNT(*) FROM Customers';
EXEC (@sqlPopulate)
END 
That's it. Happy Myanmar New Year!!!

2 comments:

  1. Vì sau khi hàng được chuyển về Việt Nam việc đổi trả hàng khá rắc rối và hầu như không thể, do đó bạn hãy xem xét thật kĩ trước khi đưa ra quyết định chọn mua để tránh phải phiền toái về sau Mua hàng trên amazon có an toàn không. Amazon là trang bán hàng trực tuyến hàng đầu của Mỹ và trên toàn thế giới với kho hàng hóa đa dạng, khổng lồ nơi bạn có tìm thấy bất kì mặt hàng nào mà mình đang cần Mua hàng trên amazon có đảm bảo không. Trong những năm gần đây, thương mại điện tử đã dần trở nên quen thuộc hơn trong đời sống của người dân ở nước ta Mua hàng trên amazon có bị đánh thuế không
    Khâu chuẩn bị chăn ga gối đệm cho ngày cưới phù hợp với phong thủy của các cặp vợ chồng, kết hợp với cấu trúc phòng ngủ là mối quan tâm chung của các cặp đôi khi mới cưới chọn màu chăn ga gối đệm theo phong thủy. Hiện tượng mất ngủ đã không còn quá xa lạ với nhiều người, sự ra đời của những bộ chăn ra gối nệm cao cấp cũng được xem là “bước ngoặt” tuyệt vời dành cho đời sống chăn ra gối nệm giá rẻ Sự cân bằng giữa năng lượng âm và dương để đạt để sự hài hòa lý tưởng trong không gian trong thuyết Ngũ hành góp phần tích cực vào việc tham khảo, lựa chọn màu sắc chăn ga gối đệm cho bạn kinh nghiệm mở đại lý chăn ga gối đệm.

    ReplyDelete