Explorando o GridView – Objetos DataSource


É muito comum trabalharmos com acesso a dados em qualquer tipo de aplicação, seja Windows, Web, Web Service, etc., e com isso, escrevemos diversos tipos de códigos para diversas operações, como por exemplo:

  • paginação
  • habilitar a ordenação
  • exibição de registro detalhado
  • edição
  • exclusão

Para que conseguíssemos desenvolver estas funcionalidades na versão anterior do ASP.NET 1.x, tínhamos que escrever bastante linhas de códigos. Nada muito exagerado, porém de certa forma por muitas vezes o código era redundante.

Como estas tarefas são bastante utilizadas em nosso dia-a-dia, a Microsoft criou controles do tipo Data Bound para não precisarmos ir diretamente ao código para criar tais funcionalidades. Esses controles são: SqlDataSource, ObjectDataSource e o XmlDataSource.

Esses controles são totalmente compatíveis com o controle que é tema deste artigo, o GridView, permitindo com esta integração, uma grande facilidade em criar aplicações que acessam e manipulam os dados de forma bem fácil e intuitiva (através das Smart Tags), permitindo assim atingir também desenvolvedores iniciantes que ainda não estão à vontade trabalhando diretamente com código.

Os controls Data Bound encapsulam a maioria das operações, que antes precisavam ser desenvolvidas para diferentes repositórios de dados. Isso tira a preocupação de definir e/ou gerir a conexão com a base de dados, a query e seus respectivos parâmetros que serão utilizados. Através de propriedades podemos especificar seus devidos valores em design-time.

Abaixo vemos a finalidade de cada um desses controles:

  • SqlDataSource: Fornece acesso à uma base de dados SQL Server.

  • ObjectDataSource: Fornece acesso à um determinado método de uma alguma classe. Estas classes geralmente encapsulam o acesso à base de dados, ou qualquer repositório, retornando uma coleção de objetos que deve ser apresentada ao usuário.

  • XmlDataSource: Fornece acesso e manipulação à um arquivo XML.

Abaixo abordaremos cada um desses controles detalhadamente.

SqlDataSource

Como já vimos, este controle é responsável por encapsular a manipulação dos dados de uma base de dados SQL Server. Temos nele propriedades essencias, como por exemplo, os comandos SelectCommand, InsertCommand, DeleteCommand e UpdateCommand, que é onde definimos os comandos (queries ou Stored Procedures) que serão executadas para cada ação.

Podemos definir estas propriedades via design (IDE), através da janelas de propriedades do Visual Studio .NET 2005 ou declarativamente no código HTML da página ASPX. Utilizando a IDE do Visual Studio .NET 2005 existem as chamadas Smart Tags, que são uma espécie de “Wizard”, onde podemos configurar passo a passo cada uma dessas propriedades, habilitando inclusive uma opção para manipular as colunas que queremos exibir ao usuário.

Depois de arrastar um SqlDataSource para o nosso WebForm, haverá um botão no canto superior direito deste que, ao clicar, um wizard é exibido para fazermos as configurações. Abaixo a Figura 1 ilustra este processo:

Figura 1 – Utilizando as Smart Tags para configuração.

Ao clicar em Configure Data Source…, uma nova janela será aberta informando as configurações à serem efetuadas para o funcionamento do objeto SqlDataSource. Isso inclui desde a escolha do banco de dados, passando pela query (ou Stored Procedure) que será executada. Há uma opção chamada Advanced que, geramos automaticamente os comandos de Insert, Delete e Update (semelhante ao que já fazemos atualmente com o Dataset e DataAdapter). As imagens abaixo ilustram este processo passo à passo:

Figura 2 – Definindo o banco de dados a ser utilizado.

Figura 3 – Gerando as queries ou Stored Procedures para as operações de CRUD.

Figura 4 – Esta opção é habilitada quando clicamos no botão Advanced… da figura anterior,
onde definimos se os comandos de CRUD serão ou não gerados automaticamente.

É importante informar que os comandos gerados automaticamente são baseados no comando de seleção. Logo, os campos que são informados na seleção refletem nos comandos de inserção e atualização. Veremos abaixo o código HTML correspondente ao nosso objeto SqlDataSource e o controle GridView, gerado em nosso arquivo ASPX:

<asp:SqlDataSource 
    ID="SqlDataSource1" 
    runat="server" 
    ConnectionString="<%$ ConnectionStrings:ConnString %>"
    SelectCommand="SELECT [UsuarioID], [Nome], [Email] FROM [Usuario]" 
    DeleteCommand="DELETE FROM [Usuario] WHERE [UsuarioID] = @original_UsuarioID" 
    InsertCommand="INSERT INTO [Usuario] ([Nome], [Email]) VALUES (@Nome, @Email)" 
    UpdateCommand="UPDATE [Usuario] SET [Nome] = @Nome, [Email] = @Email 
	WHERE [UsuarioID] = @original_UsuarioID">
    <DeleteParameters>
        <asp:Parameter Name="original_UsuarioID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="Nome" Type="String" />
        <asp:Parameter Name="Email" Type="String" />
        <asp:Parameter Name="original_UsuarioID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="Nome" Type="String" />
        <asp:Parameter Name="Email" Type="String" />
    </InsertParameters>
</asp:SqlDataSource>

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    DataSourceID="SqlDataSource1">
</asp:GridView>

Como podemos ver no código HTML correspondente ao objeto SqlDataSource, os comandos são gerados com códigos T-SQL e estão devidamente em suas respectivas propriedades. Para cada comando, há uma seção no código HTML do objeto SqlDataSource que são definidos os parâmetros que serão utilizados pela query (ou Stored Procedure), incluindo o seu nome e tipo de dado.

Depois de completamente configurado o objeto SqlDataSource, o definimos como a fonte de dados para o controle GridView, através da propriedade DataSourceID como vimos no código HTML acima. A imagem abaixo ilustra como definir o DataSource do GridView através da Smart Tag:

Figura 5 – Selecionando o Data Source do controle GridView.

ObjectDataSource

Este objeto destina-se também a vincular os dados ao controle GridView, mas utilizando uma função de uma classe qualquer que nos retorne uma coleção de objetos. Porém sem a necessidade de fazer diretamente via código. O processo de vinculação é também parecido com o objeto SqlDataSource em relação à forma de vínculo ao GridView; o que difere logicamente é o “Wizard” que é exibido para a configuração do mesmo.

Antes de exibir o wizard vamos montar o código que será responsável por resgatar os dados da base de dados, popular os objetos e, consequentemente, retornar uma coleção do mesmo. Abaixo é exibido a classe “Usuario”:

using System;

public class Usuario
{
    private int _id;
    private string _nome;
    private string _email;
    private string _endereco;
    private string _cidade;
    private string _estado;
    private string _foto;

    public int ID
    {
        get { return this._id; }
        set { this._id = value; }
    }

    public string Nome
    {
        get { return this._nome; }
        set { this._nome = value; }
    }

    public string Email
    {
        get { return this._email; }
        set { this._email = value; }
    }

    public string Endereco
    {
        get { return this._endereco; }
        set { this._endereco = value; }
    }

    public string Cidade
    {
        get { return this._cidade; }
        set { this._cidade = value; }
    }

    public string Estado
    {
        get { return this._estado; }
        set { this._estado = value; }
    }

    public string Foto
    {
        get { return this._foto; }
        set { this._foto = value; }
    }
}

Depois da classe que armazena os valores provenientes do banco de dados ou de qualquer outra repositório, vamos criar a classe que tem a finalidade de ir até o banco de dados, resgatar os dados através de objetos que já são de nosso conhecimento (SqlConnection, SqlCommand, SqlDataReader) e popular objetos do tipo Usuario, que criamos logo acima. O código abaixo é responsável por esse processo:

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() {
        List<Usuario> coll = new List<Usuario>();
        string connString = 
          WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString
        SqlConnection conn = new SqlConnection(connString);
        SqlCommand cmd = 
          new SqlCommand("SELECT UsuarioID, Nome, Email FROM Usuario", 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;
    }
}

Como vemos, a classe Usuarios possui um método público que retorna uma lista tipificada de objetos do tipo Usuario. É este método que vamos definir no objeto ObjectDataSource, que fará todo o trabalho, desde criar a instância da classe até a chamada do método e a carga do controle GridView.

Veremos abaixo o passo à passo de como configurar o objeto ObjectDataSource com esta classe e método. Ao clicar na Smart Tag e escolhendo a Configure Data Source…, temos:

Figura 6 – Selecionando o Objeto da classe de negócios.

Figura 7 – Selecionando os métodos.

Como podemos ver na Figura 7, temos as abas para definir os métodos para Select, Update, Insert e Delete. Podemos ver que é mesmo muito semelhante a forma que trabalhamos com o objeto SqlDataSource mas, neste caso, devemos informar as funções que estão na classe de negócios responsáveis por cada ação. O código HTML resultante da criação deste objeto ObjectDataSource no arquivo ASPX é:

<asp:ObjectDataSource 
    ID="ObjectDataSource1" 
    runat="server" 
    SelectMethod="ResgataUsuarios"
    TypeName="Usuarios">
</asp:ObjectDataSource>

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    DataSourceID="ObjectDataSource1">
</asp:GridView>

Uma propriedade que ainda não analisamos é a TypeName, que recebe uma String que corresponde ao nome da classe que o objeto ObjectDataSource representará, utilizando Reflection para carregar e executar o(s) método(s) deste tipo. Esta String contém o nome de um determinado tipo particalmente qualificado, que está localizado nos diretórios Bin ou App_Code. Se o componente estiver registrado no Global Assembly Cache – GAC a String conterá o tipo complemento, incluindo o Namespace. Vale lembrar que, se o componente estiver no Global Assembly Cache, você deverá fazer as devidas referências no Machine.Config ou Web.Config, dependendo da sua necessidade.

Nota Importante: Se por algum motivo a classe de regras de negócios tiver um construtor parametrizado, você deverá utilizar o evento ObjectCreating do objeto ObjectDataSource. Este evento é invocado antes da criação do objeto, permitindo customizar esta instanciação. Um dos parâmetros do evento, é um objeto do tipo ObjectDataSourceEventArgs, que possui uma propriedade (escrita/leitura) chamada ObjectInstance, que tem a responsabilidade de executar os métodos que foram definidos nas propriedades [XXX]Method. Quando esta propriedade é definida neste evento, o objeto ObjectDataSource irá respeitar, executando os métodos baseando-se nesta instância. O código abaixo exibe a forma de como customizar:

protected void ObjectDataSource1_ObjectCreating(object sender, 
    ObjectDataSourceEventArgs e){

    string conn =
        WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;    
    Usuarios usuarios = 
        new Usuarios(conn);
    e.ObjectInstance = usuarios;
}

XmlDataSource

Além dos objetos que vimos anteriormente, o ASP.NET 2.0 ainda disponibiliza um objeto nas mesmas características, mas este é utilizado para acessar arquivos XML. Este objeto é chamado de XmlDataSouce. Criei abaixo um arquivo XML chamado de Usuarios.xml, que contém uma relação de usuários para demonstrar a configuração e utilização deste objeto.

<?xml version="1.0" encoding="utf-8" ?>
<Usuarios>
    <Usuario
        Nome="Israel Aece"
        Email="israel@projetando.net"
        Cidade="Valinhos">    
    </Usuario>
    <Usuario
        Nome="Claudia Fernanda"
        Email="claudia@projetando.net"
        Cidade="Valinhos">
    </Usuario>
    <Usuario
        Nome="Juliano Aece"
        Email="juliano@projetando.net"
        Cidade="Valinhos">
    </Usuario>
    <Usuario
        Nome="Carlos Bonna"
        Email="bonna@projetando.net"
        Cidade="Campinas">
    </Usuario>
</Usuarios>

Depois do arquivo XML criado, vamos definí-lo como a fonte de dados de controle GridView utilizando o objeto XmlDataSource. A figura abaixo exibe como configurá-lo:

Figura 8 – Configurando o objeto XmlDataSource.

No campo Data File (campo obrigatório) definimos o caminho do arquivo que queremos que o objeto XmlDataSource carregue. Já no campo Tranform File você pode definir opcionalmente um arquivo com os estilos (*.xsl) para que, se necessário, você altere a estrutura do arquivo XML. O código HTML gerado por este objeto é apresentado abaixo:

<asp:XmlDataSource 
    ID="XmlDataSource1" 
    runat="server" 
    DataFile="~/Usuarios.xml">
</asp:XmlDataSource>

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    DataSourceID="XmlDataSource1">
</asp:GridView>

Tipos de Parâmetros

Quando utilizamos algum objeto de DataSource, temos ainda uma seção dentro deles que não exploramos. Esta seção é definida através dos elementos FilterParameters, SelectParameters, InsertParameters, DeleteParameters e UpdateParameters. É através deles que passamos para a query, Stored Procedure ou método quando for uma classe de negócios os valores para os parâmetros que são necessários para efetuar a operação corretamente.

Dentro desta seção podemos definir os parâmetros que serão utilizados, porém customizando-os de acordo com a sua origem, ou seja, podemos ter parâmetros provenientes de QueryStrings, variáveis de sessão, Cookies, controles do formulário, entre outros.

Para cada um destes tipos de parâmetros existe uma classe específica que é herdada diretamente da classe Parameter que está contida no namespace System.Web.UI.WebControls. A classe Parameter fornece um mecanismo para preencher os parâmetros necessários na query, Stored Procedure ou classe de negócios. É esta a classe base para todos os tipos de parâmetros do ASP.NET.

Vejamos abaixo os tipos de parâmetros suportados pelo ASP.NET, que são classes derivadas da classe Parameter:

Classe Descrição
 ControlParameter Este tipo de parâmetro é responsável por resgatar um determinado controle do WebForm através da propriedade ID que deve ser passada para este parâmetro através da propriedade ControlID. Outra propriedade essencial à este tipo de parâmetro é a PropertyName, na qual você deverá informar qual é a propriedade do controle que o ASP.NET deverá recuperar o valor. Abaixo é listado os controles e suas respectivas propriedades que são utilizadas neste cenário:

  • Label.Text
  • TextBox.Text
  • ListControl.SelectedValue
  • CheckBox.Checked
  • Calendar.SelectedDate
  • DetailsView.SelectedValue
  • GridView.SelectedValue
  • TreeView.SelectedValue
  • FileUpload.FileBytes
 CookieParameter Neste caso é passado ao parâmetro o valor contido dentro de um objeto do tipo HttpCookie. Deve-se informar através da propriedade CookieName o nome do Cookie à ser recuperado.
 FormParameter Define o valor do parâmetro com o valor que está contido dentro de um controle HTML. Deve-se informar através da propriedade FormField o nome do controle HTML à ser recuperado.
 ProfileParameter Define o valor do parâmetro com o valor que está contido dentro de uma propriedade do objeto Profile. Deve-se informar através da propriedade ParameterName o nome da propriedade do objeto Profile à ser recuperado.
 QueryStringParameter Define o valor do parâmetro com o valor que está contido dentro de uma QueryString. Deve-se informar através da propriedade QueryStringField o nome da QueryString à ser recuperado.
 SessionParameter Define o valor do parâmetro com o valor que está contido dentro de uma variável de sessão. Deve-se informar através da propriedade SessionField o nome da variável de sessão à ser recuperado.

Como todos esses parâmetros herdam da classe Parameter, os mesmos contém uma propriedade chamada DefaultValue que utilizamos para definir um valor padrão para quando o valor, controle ou propriedade dos respectivos parâmetros não estiverem disponíveis ou forem inválidos.

Abaixo veremos a utilização de dois desses parâmetros: o ControlParameter e o QueryStringParameter. O cenário do exemplo é resgatar os usuários baseando-se em um Estado (UF) informado pelo usuário, através de um TextBox (Figura 9) e QueryString (Figura 10):

<asp:SqlDataSource 
    ID="SqlDataSource1" 
    runat="server" 
    ConnectionString="<%$ ConnectionStrings:ConnString %>"
    SelectCommand="SELECT [Nome], [Email] FROM [Usuario] WHERE Estado = @UF">
    <SelectParameters>
        <asp:ControlParameter 
            ControlID="txtUF" 
            PropertyName="Text"
            Name="UF" />
    </SelectParameters>
</asp:SqlDataSource>

Figura 9 – Utilizando o parâmetro do tipo ControlParameter.

<asp:SqlDataSource 
    ID="SqlDataSource1" 
    runat="server" 
    ConnectionString="<%$ ConnectionStrings:ConnString %>"
    SelectCommand="SELECT [Nome], [Email] FROM [Usuario] WHERE Estado = @UF">
    <SelectParameters>
        <asp:QueryStringParameter 
            QueryStringField="UF" 
            Name="UF" />
    </SelectParameters>
</asp:SqlDataSource>

Figura 10 – Utilizando o parâmetro do tipo QueryStringParameter.

Como podemos certificar, o valor do parâmetro (independente de onde está vindo) é passado, neste caso, para a query definida na propriedade SelectCommand utilizando o objeto SqlDataSource.

Eventos

Como estes objetos derivam de uma classe em comum (DataSourceControl) o mesmos tem alguns eventos semelhantes. Veremos cada sum desses eventos e suas respectivas descrições listadas na tabela abaixo:

Evento Descrição
 Deleted Ocorre quando a exclusão é completada.
 Deleting Ocorre antes de executar a operação de exclusão.
 Filtering Ocorre antes de executar a operação de filtro.
 Inserted Ocorre quando a inserção é completada.
 Inserting Ocorre antes de executar a operação de inserção.
 Selected Ocorre quando a seleção é completada.
 Selecting Ocorre antes de executar a operação de seleção.
 Updated Ocorre quando a atualização é completada.
 Updating Ocorre antes de executar a operação de atualização.
 ObjectCreated* Ocorre depois que o objeto especificado na propriedade PropertyName for criado.
 ObjectCreating* Ocorre antes que o objeto especificado na propriedade PropertyName seja criado.
 ObjectDisposing* Ocorre antes que o objeto especificado na propriedade PropertyName seja destruído.

* Eventos pertencentes apenas ao objeto ObjectDataSource.

GridView.zip (674.49 kb)

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s