Quando exibimos ao cliente uma grande quantidade de dados, algumas funcionalidades se fazem essenciais para que ele possa visualizar e analisar estes dados de forma mais eficiente. Uma dessas funcionalidades é chamada de ordenação de colunas, ou Sorting.
Quando utilizamos o DataGrid da versão 1.x do ASP.NET, para poder ter esta funcionalidade, tínhamos que, através do evento SortCommand do DataGrid, recuperar a coluna que foi clicada pelo usuário e invocar novamente o procedimento que resgata os dados e popula o Datagrid, informando a coluna que será utilizada para efetuar a ordenação. Agora, com o controle GridView, conseguimos obter esta funcionalidade sem a escrita de nenhuma linha de código, salvo quando utilizamos o objeto ObjectDataSource.
Utilizando o objeto SqlDataSouce
Para habilitarmos esta funcionalidade no controle GridView utilizando o objeto SqlDataSource devemos clicar na Smart Tag e marcar o CheckBox chamado Enable Sorting, como é mostrado na imagem abaixo:
|
|
| Figura 1 – Habilitando a Ordernação de Registros. |
Habilitando esta opção, o controle GridView já fará a ordenação dos registros automaticamente. Através do código HTML abaixo da página ASPX, vemos como o mesmo ficou configurado:
<asp:GridView
ID="GridView1"
runat="server"
DataSourceID="SqlDataSource1"
AutoGenerateColumns="False"
AllowSorting="True"
DataKeyNames="UsuarioID">
<Columns>
<asp:BoundField
DataField="Nome"
HeaderText="Nome"
SortExpression="Nome" />
<asp:BoundField
DataField="Email"
HeaderText="Email" />
</Columns>
</asp:GridView>
|
Analisando o código acima podemos notar a propriedade SortExpression da coluna do tipo BoundField. É através desta propriedade que o ASP.NET se encarrega de ordenar a coluna automaticamente clicada pelo usuário e, no caso acima, somente a ordenação para a coluna Nome está habilitada. Algo importante à dizer é que a propriedade SortExpression deve conter exatamente o nome da coluna da fonte de dados para que a ordernação seja possível.
O objeto SqlDataSource possui um propriedade chamada DataSourceMode. Através desta propriedade você define ao objeto SqlDataSource qual será a forma, Dataset ou DataReader, que ele utilizará para resgatar os dados da base de dados. Por padrão, ou seja, quando não definimos esta propriedade, o SqlDataSource faz isso utilizando um objeto do tipo Dataset.
como já vimos acima, essa ordenação é feita automaticamente somente quando definimos a propriedade DataSourceMode como Dataset (ou quando omitimos). Quando definimos esta propriedade como DataReader, sem mais nenhuma outra configuração no objeto SqlDataSource, receberemos a seguinte exceção:
|
|
| Figura 2 – Exceção causada utilizando a propriedade DataSourceMode incorretamente. |
Quando definimos o objeto DataReader para recuperar os dados e quisermos também ter a ordenação dos registros, devemos fazer alguns outros ajustes no objeto SqlDataSource para alcançar este objetivo. Vamos analisá-los passo à passo abaixo:
-
A propriedade DataSourceMode: Definimos para DataReader quando queremos utilizar este para recuperar os dados da fonte de dados.
-
A propriedade SelectCommand: Por design, somente conseguimos isso utilizando uma Stored Procedure. É nesta propriedade que devemos definir o nome da Stored Procedure que será responsável por recuperar os dados.
-
A propriedade SelectCommandType: Como a propriedade SelectCommand estará armazenando uma Stored Procedure, através da SelectCommandType informaremos exatamente isso, ou seja, informar ao ASP.NET que é uma Stored Procedure ao invés de um Sql Statement.
-
A propriedade SortParameterName: É justamente o parâmetro que estará dentro da Stored Procedure e que será responsável pela ordenação. Automaticamente o ASP.NET associa o nome da coluna clicada pelo usuário (a propriedade SortExpression) como o value deste parâmetro. Nota: Não há necessidade de colocar o “@” no nome deste parâmetro.
Para exemplificar o uso do objeto DataReader para recuperar os dados através do SqlDataSource e utilizar a ordenação dos dados, abaixo é exibido o código HTML da página ASPX e a respectiva Stored Procedure (que está definida na propriedade SelectCommand):
<asp:SqlDataSource
ID="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:ConnString %>"
DataSourceMode="DataReader"
SortParameterName="Coluna"
SelectCommand="Sorting"
SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
<asp:GridView
ID="GridView1"
runat="server"
DataSourceID="SqlDataSource1"
AutoGenerateColumns="False"
AllowSorting="True"
DataKeyNames="UsuarioID">
<Columns>
<asp:BoundField
DataField="Nome"
HeaderText="Nome"
SortExpression="Nome" />
</Columns>
</asp:GridView>
|
ALTER PROCEDURE dbo.Sorting @Coluna As Varchar(30) AS DECLARE @Query As NVarchar(4000) SET @Query = 'SELECT Nome, Email, UsuarioID FROM Usuario' IF @Coluna != '' SET @Query = @Query + ' ORDER BY ' + @Coluna EXECUTE sp_executesql @Query |
Como vemos, a Stored Procedure recebe um parâmetro que será utilizado para efetuar a ordenação. Reparem que o nome do parâmetro da Stored Procedure é o mesmo que está definido na propriedade SortParameterName do objeto SqlDataSource. A verificação do valor deste parâmetro, se é ou não vazio, é necessária pois a primeira vez que a página for carregada não é passado nenhum valor à ele.
Utilizando o objeto ObjectDataSouce
Ao contrário do objeto SqlDataSouce, o objeto ObjectDataSouce necessita de algum código adicional justamente porque o mesmo está ligado à uma classe de regras negócios, a qual deve contemplar a ordenação de um result-set qualquer. O processo de ordenação para o objeto ObjectDataSource é basicamente idêntico ao mostrado acima com o objeto SqlDataSource, apenas contemplando nos parâmetros do método que retorna a coleção de objetos uma string que representará a coluna à ser ordenada.
Como a parte de vinculação do objeto ObjectDataSouce ao controle GridView é semelhante à forma acima, vamos diretamente analisar o código que será responsável pela ordenação de registros:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Configuration;
using System.Collections.Generic;
public class Usuarios
{
public List<Usuario> ResgataUsuarios() {
return ResgataUsuarios(string.Empty);
}
public List<Usuario> ResgataUsuarios(string coluna) {
List<Usuario> coll = new List<Usuario>();
string connString =
WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString
SqlConnection conn = new SqlConnection(connString);
string query = "SELECT UsuarioID, Nome, Email FROM Usuario";
if(coluna != string.Empty)
query += " ORDER BY " + coluna;
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataReader dr = null;
try
{
conn.Open();
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while(dr.Read()){
Usuario u = new Usuario();
u.ID = dr.GetInt32(0);
u.Nome = dr.GetString(1);
u.Email = dr.GetString(2);
coll.Add(u);
}
}
finally {
if (dr != null)
dr.Close();
}
return coll;
}
}
|
Analisando o código acima temos sobrecarga para o método ResgataUsuarios, onde em um deles recebemos uma string que corresponde à coluna a ser ordenada. Como fizemos com a Stored Procedure, neste método também analisamos se o parâmetro é ou não vazio pois, a partir disto, acrescentamos a cláusula ORDER BY, se necessário. Há ainda pequenas configurações a serem feitas no objeto ObjectDataSource, ou seja, no caso deste objeto, em sua Smart Tag, não temos o CheckBox para habilitar a Ordenação, tendo assim que recorrer à janela de propriedade e marcar a propriedade AllowSorting como True.
Além disso precisamos também definir a propriedade SortParameterName onde, neste caso, irá o nome do parâmetro responsável pela ordenação do nosso método ResgataUsuarios, que é coluna. Vejamos abaixo o código HTML resultante na página ASPX depois dessas configurações:
<asp:ObjectDataSource
ID="ObjectDataSource1"
runat="server"
SelectMethod="ResgataUsuarios"
SortParameterName="coluna"
TypeName="Usuarios">
</asp:ObjectDataSource>
<asp:GridView
ID="GridView1"
runat="server"
AutoGenerateColumns="False"
DataSourceID="ObjectDataSource1"
AllowSorting="True">
<Columns>
<asp:BoundField
DataField="Nome"
HeaderText="Nome"
SortExpression="Nome" />
</Columns>
</asp:GridView>
|
Automaticamente em runtime, o ASP.NET define o valor da propriedade SortExpression clicada pelo usuário como value do parâmetro do método ResgataUsuarios. Essa atribuição é possível pois já temos mapeado na propriedade SortParameterName o nome do parâmetro responsável pela ordenação do método referido.
Observação Importante: A propriedade SortParameterName é extremamente importante, independentemente de qual objeto de Data Source utilizamos no controle GridView: isso porque podemos ter vários parâmetros na Stored Procedure ou mesmo no método da classe de negócios.

