When you open the page in Listing 18.20, the GridView displays its paging interface, which you can use to navigate between different pages of records see Figure 18.5.. LISTING 18.24 Get
Trang 1When you open the page in Listing 18.20, the GridView displays its paging interface,
which you can use to navigate between different pages of records (see Figure 18.5)
FIGURE 18.5 Displaying multiple pages with data source paging
NOTE
The paging mechanism described in this section is based on the mechanism used by
the Microsoft ASP.NET forums at http://www.asp.net/forums and the XBOX forums at
http://www.xbox.com Both of these websites handle an incredible number of message
posts every day The forums software was written with ASP.NET and is available from
TelligentSystems (www.telligentsystems.com) as part of their Community Server
product
If temporary tables make you anxious, you have an alternative when working with
Microsoft SQL Server 2005 or 2008 You can take advantage of the new ROW_NUMBER()
function to select a range of rows The ROW_NUMBER() function automatically calculates the
sequential number of a row within a resultset
The modified stored procedure in Listing 18.24 does the same thing as the stored procedure
in Listing 18.23 However, the modified stored procedure avoids any temporary tables
Trang 2LISTING 18.24 GetPagedMovies2005.sql
CREATE PROCEDURE dbo.GetPagedMovies2005
(
@StartRowIndex INT,
@MaximumRows INT
)
AS
WITH OrderedMovies AS
(
SELECT
Id,
ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber
FROM Movies
)
SELECT
OrderedMovies.RowNumber,
Movies.Id,
Movies.Title,
Movies.Director
FROM
OrderedMovies
JOIN Movies
ON OrderedMovies.Id = Movies.Id
WHERE
RowNumber BETWEEN (@StartRowIndex + 1) AND (@startRowIndex + @maximumRows + 1)
User Interface Sorting
If you need to sort the records displayed by the GridView control, the easiest type of
sorting to enable is user interface sorting When you take advantage of user interface
sorting, the records are sorted in the server’s memory
For example, the page in Listing 18.25 contains a GridView that has its AllowSorting
property set to the value True The GridView is bound to an ObjectDataSource that
repre-sents the Employees database table (see Figure 18.6)
Trang 3LISTING 18.25 ShowUISorting.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show User Interface Sorting</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdEmployees”
DataSourceID=”srcEmployees”
AllowSorting=”True”
Runat=”server” />
<asp:ObjectDataSource
id=”srcEmployees”
TypeName=”EmployeesUISorting”
SelectMethod=”GetEmployees”
Runat=”server” />
FIGURE 18.6 Sorting records with user interface sorting
Trang 4</div>
</form>
</body>
</html>
The ObjectDataSource control in Listing 18.25 is bound to the component in Listing
18.26 The GetEmployees() method returns an ADO.NET DataSet object When taking
advantage of user interface sorting, the ObjectDataSource control must represent the right
type of data source The right type of data source includes DataSet, DataTable, and
DataView controls
LISTING 18.26 EmployeesUISorting.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
public class EmployeesUISorting
{
private static readonly string _conString;
public static DataSet GetEmployees()
{
// Initialize ADO.NET objects
string selectText = “SELECT Id,FirstName,LastName,Phone FROM Employees”;
SqlDataAdapter dad = new SqlDataAdapter(selectText, _conString);
DataSet dstEmployees = new DataSet();
// Fill the DataSet
using (dad)
{
dad.Fill(dstEmployees);
}
return dstEmployees;
}
static EmployeesUISorting()
{
_conString =
➥WebConfigurationManager.ConnectionStrings[“Employees”].ConnectionString;
}
}
Trang 5User interface sorting is convenient You can enable this type of sorting by setting a single
property of the GridView control Unfortunately, just as with user interface paging, some
serious performance drawbacks result from user interface sorting All the records from the
underlying database must be loaded and sorted in memory This is a particular problem
when you want to enable both sorting and paging at the same time In the next section,
you learn how to implement data source sorting, which avoids this performance issue
Data Source Sorting
Imagine that you are working with a database table that contains 3 billion records and
you want to enable users to both sort the records and page through the records contained
in this table In that case, you want to implement both data source sorting and paging
The page in Listing 18.27 contains a GridView and ObjectDataSource control The
GridView has both its AllowSorting and AllowPaging properties enabled (see Figure 18.7)
FIGURE 18.7 Paging and sorting database records
LISTING 18.27 ShowDSSorting.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
Trang 6<style type=”text/css”>
.employees td,.employees th
{
font:16px Georgia,Serif;
padding:5px;
}
a
{
color:blue;
}
</style>
<title>Show Data Source Sorting</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdEmployees”
DataSourceID=”srcEmployees”
AllowSorting=”true”
AllowPaging=”true”
PageSize=”3”
CssClass=”employees”
Runat=”server” />
<asp:ObjectDataSource
id=”srcEmployees”
TypeName=”EmployeesDSSorting”
SelectMethod=”GetEmployees”
SelectCountMethod=”GetEmployeeCount”
EnablePaging=”true”
SortParameterName=”sortExpression”
Runat=”server” />
</div>
</form>
</body>
</html>
The ObjectDataSource control in Listing 18.27 represents the EmployeesDSSorting
component in Listing 18.28 The ObjectDataSource control includes a SortParameterName
property When this property is present, the ObjectDataSource control uses data source
sorting instead of user interface sorting
Trang 7LISTING 18.28 EmployeesDSSorting.vb
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.Configuration
Public Class EmployeesDSSorting
Private Shared ReadOnly _conString As String
Public Shared Function GetEmployees(ByValsortExpression As String, ByVal
startRowIndex As Integer, ByVal maximumRows As Integer) As SqlDataReader
‘ Initialize connection
Dim con As New SqlConnection(_conString)
‘ Initialize command
Dim cmd As New SqlCommand()
cmd.Connection = con
cmd.CommandText = “GetSortedEmployees”
cmd.CommandType = CommandType.StoredProcedure
‘ Create parameters
cmd.Parameters.AddWithValue(“@SortExpression”, sortExpression)
cmd.Parameters.AddWithValue(“@StartRowIndex”, startRowIndex)
cmd.Parameters.AddWithValue(“@MaximumRows”, maximumRows)
‘ Execute command
con.Open()
Return cmd.ExecuteReader(CommandBehavior.CloseConnection)
End Function
Public Shared Function GetEmployeeCount() As Integer
Dim context As HttpContext = HttpContext.Current
If context.Cache(“EmployeeCount”) Is Nothing Then
context.Cache(“EmployeeCount”) = GetEmployeeCountFromDB()
End If
Return CType(context.Cache(“EmployeeCount”), Integer)
End Function
Private Shared Function GetEmployeeCountFromDB() As Integer
Dim result As Integer = 0
Trang 8‘ Initialize connection
Dim con As SqlConnection = New SqlConnection(_conString)
‘ Initialize command
Dim cmd As SqlCommand = New SqlCommand()
cmd.Connection = con
cmd.CommandText = “SELECT Count(*) FROM Employees”
‘ Execute command
Using con
con.Open()
result = CType(cmd.ExecuteScalar(), Integer)
End Using
Return result
End Function
Shared Sub New()
_conString =
➥WebConfigurationManager.ConnectionStrings(“Employees”).ConnectionString
End Sub
End Class
The GetEmployees() method in the component in Listing 18.28 calls a stored procedure to
sort and page records The stored procedure, named GetSortedEmployees, returns a sorted
page of records from the Employees database table This stored procedure is contained in
Listing 18.29
LISTING 18.29 GetSortedEmployees.sql
CREATE PROCEDURE GetSortedEmployees
(
@SortExpression NVarChar(100),
@StartRowIndex INT,
@MaximumRows INT
)
AS
Create a temp table to store the select results
CREATE TABLE #PageIndex
(
IndexId INT IDENTITY (1, 1) NOT NULL,
RecordId INT
Trang 9)
INSERT into the temp table
INSERT INTO #PageIndex (RecordId)
SELECT Id FROM Employees
ORDER BY
CASE WHEN @SortExpression=’Id’ THEN Id END ASC,
CASE WHEN @SortExpression=’Id DESC’ THEN Id END DESC,
CASE WHEN @SortExpression=’FirstName’ THEN FirstName END ASC,
CASE WHEN @SortExpression=’FirstName DESC’ THEN FirstName END DESC,
CASE WHEN @SortExpression=’LastName’ THEN LastName END ASC,
CASE WHEN @SortExpression=’LastName DESC’ THEN LastName END DESC,
CASE WHEN @SortExpression=’Phone’ THEN Phone END ASC,
CASE WHEN @SortExpression=’Phone DESC’ THEN Phone END DESC
Get a page of records
SELECT
Id,
FirstName,
LastName,
Phone
FROM
Employees
INNER JOIN #PageIndex WITH (nolock)
ON Employees.Id = #PageIndex.RecordId
WHERE
#PageIndex.IndexID > @StartRowIndex
AND #PageIndex.IndexID < (@StartRowIndex + @MaximumRows + 1)
ORDER BY
#PageIndex.IndexID
The stored procedure in Listing 18.29 uses SQL CASE functions to sort the records before
they are added to the temporary table Unfortunately, you can’t use a parameter with an
ORDER BY clause, so the sort columns must be hard-coded in the CASE functions Next, a
page of records is selected from the temporary table
NOTE
As an alternative to the data source sorting method described in this section, you can
use LINQ to SQL For more information on LINQ to SQL, see Chapter 20
Trang 10Filtering Data
You can supply the ObjectDataSource control with a filter expression The filter
expres-sion is applied to the data returned by the control’s select method A filter is particularly
useful when used in combination with caching You can load all the data into the cache
and then apply different filters to the cached data
NOTE
You learn how to cache data with the ObjectDataSource control in Chapter 29,
“Caching Application Pages and Data.”
For example, the page in Listing 18.30 contains a DropDownList and GridView control The
DropDownList displays a list of movie categories, and the GridView displays matching
movies (see Figure 18.8)
FIGURE 18.8 Filtering movies with the ObjectDataSource control