Desenvolvimento - ADO.NET

.NET: ADO.NET para iniciantes

O requisito para este artigo é que você conheça o básico de banco de dados começando no MS ACCESS e partindo para o MS SQL Server 2000.x ou MSDE. Utilizaremos a partir deste ponto a sigla SGDB para nos referimos ao servidor de banco de dados...

por Ramon Durães



Não tem momento exato para começar, mas quando se inicia um estudo, é importante partir do principio de que tem que buscar o básico e então ir avançando até a evolução no conhecimento. Existem hoje muitas revistas, websites, e autores de altíssima qualidade aqui no Brasil. Mas sempre percebo que falta material para quem está começando. É uma tendência natural sempre surgirem novos artigos tratando de assuntos cada vez mais avançados ficando o novo público perdido, pois não encontra artigos básicos. Recebi diversos e-mails me cobrando um artigo como esse. Então resolvi tomar como meta direcionar vários artigos a esse propósito.

O requisito para este artigo é que você conheça o básico de banco de dados começando no MS ACCESS e partindo para o MS SQL Server 2000.x ou MSDE. Utilizaremos a partir deste ponto a sigla SGDB para nos referimos ao servidor de banco de dados.

Introdução a Banco de Dados

O banco de dados sempre foi um ponto forte na aplicação. Sendo que uma falha na modelagem (preparação) pode prejudicar o desempenho da própria aplicação. Portanto é fundamental seu conhecimento para que possa preparar da melhor forma possível, tal como dimensionar a solução a ser adotada. Dentre as opções disponíveis no mercado vamos rever as seguintes:

  • MS ACCESS - Este é um ótimo banco de dados principalmente para quem está começando pela facilidade de utilização, você rapidamente aprende como utilizá-lo. Seu uso é recomendado apenas como doméstico e é uma ótimo caminho para, depois que se aprender, passar a utilizar o MS SQL Server
  • MS SQL Server - Este é um servidor de banco de dados profissional, e é atualmente um dos melhores do mercado. Um grande destaque nesse produto é sua facilidade de operação, resultando em um ótimo produto e um custo mais baixo de manutenção, tal como custo de aquisição se comparado a produtos similares no mercado. Pode ser implementado de forma individual ou em paralelo (Cluster) com suporte a tolerância de falhas, desde é claro que possua hardware e software para isso.
  • MS MSDE - Este é uma versão gratuita e similar ao SQL Server e tem com objetivo você desenvolver sua aplicação e testar sem a necessidade de ter o SQL Server. Para evitar o uso indevido essa versão conta com recurso que resulta em perda de desempenho no caso de mais de 5 transações simultâneas tal como limitação do tamanho do arquivo de dados. Eu recomendo seu.

Em todo artigo utilizaremos o MS SQL Server , por ser um servidor de banco de dados, ele armazena dentro do mesmo vários bancos de dados conforme a Figura 1, ficando cada aplicação utilizando um ou vários desses bancos, bastando é claro que tenha direito de acesso para isso. Todos nossos exemplos será no Database Northwind. Sendo este um banco de dados padrão que vem junto com o SQL Server já pra ser utilizado para testes pois já possui dados.

Estrutura do MS SQL Server

Figura 1: Estrutura do MS SQL Server

Dentro de cada banco de dados temos as Tabelas (Tables) conforme Figura 2 e dentro das tabelas temos as colunas (Column) aonde definimos que tipo de dados vamos armazenar conforme Figura 3.

Demonstrando as Tabelas (Tables)

Figura 2: Demonstrando as Tabelas (Tables).

Estrutura da tabela e colunas (Colunm)

Figura 3: Estrutura da tabela e colunas (Colunm).

Conforme observado na Figura 03, a Coluna ProductID vai armazenar dados do tipo Inteiro e não vai aceitar nulo ou seja, essa coluna é de preenchimento obrigatório.

A maioria dos servidores de banco de dados possui suporte a Transact-SQL que é um protocolo padrão entre os SGDB para manipulação dos dados. O MS SQL Server oferece o utilitário chamado SQL Query Analyzer que é um console para utilização dos comandos SQL conforme Figura 4, está realizando uma consulta por meio do comando Select.

Consultando dados usando Query Analyzer

Figura 4: Consultando dados usando Query Analyzer.

Principais comandos SQL:

  • Select (Selecionar registros)
  • Delete (Excluir registros)
  • Update (Atualizar registros)
  • Insert (Inserir registros)
  • Where (Utilizando em conjunto com select, update, delete para impôr uma condição para processar o comando)

Exemplos:

  • Select * from Products where ProductID = 1 (Seleciona todos registros da tabela produtos cuja coluna ProductID tenha valor igual a 1)
  • Delete Products where ProductID = 1 (Exclui todos registros da tabela produtos cuja coluna ProductID tenha valor igual a 1)
  • Update Products set ProductName = "Chair" where ProductID = 1 (Atualiza todos registros na tabela produtos, coluna ProductName para "Chair" cuja coluna ProductID=1)
  • insert into Products (ProductName, SupplierID, CategoryID, QuantityPerUnit) values ("Telefone",1,1,1) (Inclui uma linha na tabela Products)

Concluída essa introdução pesquise mais detalhadamente sobre o funcionamento do banco de dados e outras facilidades oferecidas como relacionamento entre tabelas, integridade, constraints, procedures, views, triggers, backup e como gerar o diagrama do mesmo.

Histórico do acesso aos Dados.

Logo no início, para se ter acesso às informações do banco de dados era necessário ter vasto conhecimento das API de comunicação, e o programador acabava implementando seu código exclusivamente para cada versão de driver como a DBLIB (SQL Server), dedicando com isso muito tempo a este tipo de implementação. Com o crescimento do mercado e a persistência desse problema foi criado em 1990 com apoio da Microsoft e um consórcio de empresas, o padrão ODBC (Open DataBase Connectivy). Que é uma camada intermediária encarregada de cuidar da comunicação com a API deixando para o programador uma interface única e padrão para todo acesso ao SGDB confira na Figura 4a.

Demonstrando ODBC

Figura 5: Demonstrando ODBC

A partir do sucesso do ODCB e da experiência já estabelecida e necessidade de evolução foram surgindo outras propostas como o DAO (Data Access Objects) focado no MS ACCESS, sendo substituído logo depois pelo RDO (Remote Data Objects), uma vez que o DAO era realmente lento em conjunto com o ODBC.

O grande avanço da época deu-se em torno do OLEDB que se assemelhou muito com a arquitetura do ODCB porém trouxe a implementação de interfaces COM e a estratégia da Microsoft UDA (Universal Data Access) com objetivo de armazenamento distribuído, como desde planilha até e-mails. Semelhante ao ODBC, o OLEDB também foi sucesso sendo aderido até por banco de dados de padrão aberto. Para facilitar sua utilização foi criado o ADO (Activex Data Objects) com objetivo de consumir os recursos oferecidos pelos OLEDB.

O que podemos concluir desse breve histórico é que foram criadas várias camadas de acesso ao banco de dados, com objetivo de simplificar e padronizar sua utilização. Isso realmente foi fundamental para o desenvolvimento e evolução das aplicações deixando o padrão OLEDB em conjunto com o ADO na liderança no acesso a dados devido a um melhor desempenho no acesso a dados. Sendo utilizando por diversas soluções ficando o padrão ODBC para as soluções não compatíveis com ODBC. Sendo assim vale ressaltar que mesmo usando OLEDB ou ODBC a aplicação vai ter uma perda de desempenho pois vai ter um camada intermediária entre sua aplicação e as APIs de acesso a dados.O que é ADO.NET? Já faz muito tempo que a Microsoft vem investindo em criar uma interface amigável de acesso a dados para as aplicações de forma a se obter os melhores recursos, chamada anteriormente de ADO, mecanismo esse que ainda é utilizado por diversas aplicações inclusive de outros fornecedores ver modelo na Figura 4b.

Modelo ADO

Figura 6: Modelo ADO

O ADO.NET é uma completa reformulação desde mecanismo de acesso a dados, sendo uma nova geração dessa arquitetura completamente integrado ao .NET Framework oferecendo um vasto número de classes resultando numa fácil e eficiente comunicação com o SGDB permitindo todas operações necessárias.

Por ser integrado ao .NET tem o mesmo suporte a OOP, Compilação, Linguagens, Gerenciado, Coletor de lixo e principalmente acesso nativo ao banco de dados sem intermediários "OLEDB" ou "ODBC". Confira na Figura 4c.

Modelo ADO.NET com acesso nativo

Figura 7: Modelo ADO.NET com acesso nativo

Agora o acesso tornou-se mais otimizado e desconectado. Foi criado um repositório baseado em XML para que permita uma maior integração de dados entre os mais diversos sistemas de armazenamentos diferentes.

Para uma melhor compreensão vamos imaginar um cenário em que a geladeira de sua casa é o ADO.NET e o supermercado é o repositório de dados SGDB conforme Figura 5.

Portanto quando você vai ao supermercado e compra melão, cenoura e beterraba, coloca na sua sacola e traz pra casa, está neste momento abrindo uma conexão com banco, efetuando uma consulta usando Transact-SQL e recuperando os dados. Dando seqüência ao nosso cenário você normalmente pegaria essas compras (melão, cenoura e beterraba) e distribuía pela geladeira em sua casa. Este seria apenas um modelo estabelecido pra melhor organizar, mas para o ADO.NET é diferente. Você no momento de armazenar não iria conseguir colocar melão e frutas na mesma localização, pois seria de tipos diferentes. Ou seja frutas é diferente de verduras, implicando assim que não são do mesmo tipo. Dando seqüência sabemos que nossa geladeira é ADO.NET por isso já temos na tela a quantidade de cada itens: Frutas/Verduras para lhe oferecer acesso com facilidade a todos itens, sem ter que abrir e sair procurando. Fazendo isso estaríamos exemplificando o que seria o DataSet que veremos posteriormente.

Comparando ADO.NET

Figura 8: Comparando ADO.NET

Ao longo desse artigo estaremos apresentando muitas novidades e a primeira delas será o acesso nativo a SGDB.

Conforme apresentamos no histório sobre acesso a banco de dados, ao longo do tempo teve-se uma necessidade de se criar uma camada para padronizar o acesso, dentre as diversas tentativas prevaleceu o ODBC e OLEDB sendo inclusive suportados pelo novo ADO.NET, porém o mesmo agora dispõem de meios para acessar o SGBD de forma nativa sem a necessidade de intermediários já citados. Resultando em um acesso muito mais rápido como se estivesse implementando diretamente as APIs nativas do SGDB. As principais classes estão organizadas nos Namespaces (Espaço de nomes, destinado a organizar classes) abaixo:

  • System.data.SqlClient (SQL Server 7.x ou superior) (Nativo)
  • System.data.OracleClient (Oracle) (Nativo)
  • System.data.OleDb (Access e todos outros banco de dados do mesmo padrão)
  • System.data.ODBC (Todos bancos do padrão)

Portanto conforme Figura 6 a partir de agora sempre que for utilizar SQL Server 7.x dê preferência para utilizar as classes SQLClient e usar de todos benefícios das classes nativas.

Acesso nativo ao SGDB

Figura 9: Acesso nativo ao SGDB (Alto desempenho)

Compreendida as diferenças entre acesso nativo e acesso usando intermediários poderemos dividir o acesso do ADO.NET em duas partes Conectado (DataReader) e Desconectado (DataSet). Vamos comparar as diferenças entre ambos na Tabela 01:

Tabela 1: Comparativo DataSet x DataReader

Observaremos um detalhamento nas Tabelas 02 e 03.

Tabela 2: Detalhamento DataReader (Conectado)

DataReader (Conectado)
Connection Fornecesse o acesso ao banco de dados, nessa classe que você informa os dados de acesso ao banco de dados como usuário e senha. “ConnString”
Command Nesta classe você fornece a query sql (select,delete,insert,update, procedure) para processar no banco de dados
DataReader Faz a leitura dos registros no banco de dados.

Tabela 3: Detalhamento DataSet DataSet (Desconectado)

DataSet (Desconectado)
Connection Fornecesse o acesso ao banco de dados, nessa classe que você informa os dados de acesso ao banco de dados como usuário e senha. “ConnString”
Command Nesta classe você fornece a query sql (select , procedure) para processar no banco dedados
DataAdapter Faz a leitura do banco de dados, extrai todos os dados de acordo com o command e preenche o DataSet
DataSet Repositório de dados baseado em XML que pode ser transportado pelos webservices.

Trataremos com maiores detalhes sobre DataSet e sobre DataReader nos próximos tópicos, neste momento observe na Figura 07, a representação das classes apresentadas na Tabelas 01, 02 e 03.

Modelo de acesso a dados

Figura 10: Modelo de acesso a dados (DataReader e DataSet)A classe

Connection é utilizada em qualquer tipo de acesso ao SGBD sendo ele conectado ou não e a mesma recebe um parâmetro muito importante de acordo com o tipo de banco de dados que você vai utilizar. Tal como se você estivesse utilizando OLEDB vai passar um parâmetro, se for ODBC vai passar outro. Veja alguns exemplos na Tabela 04.

Tabela 4: Exemplos de string de conexão

Connection Exemplo
SQLClient Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;
OleDB (SqlServer) Provider=SQLOLEDB.1;Data Source=localhost;Initial Catalog=Northwind;User ID=sa;Password=;
OleDb (Access) Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\db\ northwind.mdb;Persist Security Info=False;

Lembre sempre de verificar se sua string de conexão é a adequada para o seu SGDB e para classe do ADO.NET que você está utilizando. Sendo que sua preferência será primeiro classes nativas (SQLClient, OracleClient) depois OleDb e por último ODBC.

Outra grande novidade é a melhoria no suporte a transações durante o processo de comunicação com o SGDB. Transações é a capacidade de retornar as alterações feitas caso tenha algum problema. Isso é muito comum de se implementar dentro do banco de dados, agora ficou muito fácil de se implementar também no código, inclusive com suporte a Save Point, ou seja, retorna a um determinado ponto caso tenha alguma falha processando o Transact-SQL.

DataBind

Este agora é um termo muito utilizado no .NET pois é a capacidade do controle de automaticamente ler um DataReader ou DataSet e exibir os dados na tela, seja um ListBox, DataGrid, DropDown...

Utilizando deste recurso o programador não precisa mais fazer loop no retorno do banco de dados para popular estes controles. A única atenção que você precisa ter é que um DataReader só pode ser lido uma vez. Por isso ele somente carrega um controle. Já o DataSet por ser desconectado pode ser lido quantas vezes for necessárias e pode carregar mais de um controle.

As principais propriedades encontradas nos controles para usar o recurso DataBind são:

  • DataSource (Define fonte de dados)
  • DataBind (Aciona a leitura da fonte de dados)
  • DatavalueField (Define valor para ListBox, Dropdown)
  • DatatextField (Define texto para ListBox, Dropdown que será apresentado na tela)

As propriedades DataValueField e DataTextField devem ser preenchidas com o nome da coluna do banco de dados.

Utilizando o DataReader

É a forma de acesso mais rápido à base de dados e tem um consumo muito baixo de memória, pois dispõe de menos recursos em cima dos dados retornados, uma vez que só vai numa direção, sem retorno. Porém como já vimos só consegue utilizar o DataReader para carregar apenas um controle.

Para cada classe de acesso você usa também um DataReader específico. Por exemplo, para classe SQLClient, usa-se o SqlDataReader e para OleDb usa-se OleDbDataReader e assim por diante pois cada classe tem implementações especificas.

O DataReader se assemelha muito ao ADO você precisa explicitamente abrir e fechar a conexão (Connection) com o SGDB. Conforme Figura 07 pra utilizar essa classe você vai precisar dos seguintes passos.

  1. Connection - Abre e fecha conexão, necessita de uma string de acesso conforme Tabela 04.
  2. Command - Vai porcessar seu comando Transaction-SQL no SGDB.
  3. DataReader - Faz a leitura do retorno

Até este ponto você deve estar achando muito fácil acessar o banco de dados e realmente é muito simples mesmo, não tem por que ser complicado. Outra questão importante é que o DataReader somente lê o retorno do banco de dados (Read Only). Mas dependendendo do comando SQL que você esteja utilizando você conseguirá excluir, alterar, inserir. O termo somente leitura é após o processamento do SQL no SGDB, ou seja depois que o Command já processou e o DataReader está recebendo a resposta.

Como o DataReader do ADO.NET é muito parecido com o ADO que utilizávamos antigamente vamos observar o código abaixo e depois criaremos um exemplo similar.

Listagem 1: Exemplo código

<%
"Arquivo: Teste.asp
set conn = server.createobject("adodb.connection") 
Conn.Open "Provider=SQLOLEDB.1;Data Source=localhost;Initial Catalog=Northwind;User ID=sa;Password=;"
sql="select * from Products"
set rs=Conn.Execute(SQL)
do while not rs.eof
response.write cstr(rs.fields("ProductID"))+"<BR>"
response.write cstr(rs.fields("ProductName"))+"<hr>"
rs.movenext
loop
Conn.Close
rs.Close
set rs=nothing
set conn=nothing
%>

Esse código é de uma página teste.asp que está acessando SGDB SQL Server utilizando OleDB, vamos agora criar um código similar utilizando ADO.NET e como vamos usar SQL Server já vamos montar o exemplo usando a classe SQLClient. Para começar adicione uma nova página ao seu projeto, no solution explorer botão direito>Add Web Form e coloque o nome teste.aspx, feito isso e já tendo a página carregada efetue dois cliques na mesma para ir para parte do código e modifique conforme conteúdo da Listagem 2.

Listagem 2: Código para utilizar SqlDataReader

Imports System.Data
Imports System.Data.SqlClient
"Imports System.Data.OleDb

Public Class teste 
    Inherits System.Web.UI.Page  
    Private Sub Page_Load _
    (ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load 

        Dim conn As New SqlConnection "Criando objeto Connection 
        Dim cmd As New SqlCommand "Criando objeto Command
        Dim dr As SqlDataReader "Criando objeto DataReader

        conn.ConnectionString = _
           "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;" 

        cmd.Connection = conn 
        cmd.CommandText = "Select * from Products" 
        cmd.CommandType = CommandType.Text

        conn.Open() "Abrindo Conexão 

        dr = cmd.ExecuteReader 

        Do While dr.Read 

            Response.Write(Convert.ToString(dr("ProductID")) + "<BR>") 
            Response.Write(Convert.ToString(dr("ProductName")) + "<HR>") 

        Loop 

        conn.Close()  "Fechando Conexão
        dr.Close() 
        conn.Dispose() 

    End Sub 

End Class

Observando o código da Listagem 2 localize o comando Imports System.Data e Imports System.Data.SqlClient, este comando está carregando as classes de acesso a dados, caso você fosse utilizar OleDB deveria utilizar o referido NameSpace conforme comentado no código. Efetue o Build e teste, terá o mesmo resultado da página feita em asp, porém uma página mais rápida, pois está utilizando código compilado e de acesso nativo via SqlClient.

Digamos que você queria fazer uma rotina para excluir um registro ou grupo de registro no banco de dados, conforme já falamos nesse artigo, basta você modificar a consulta SQL colocando um comando Delete vejamos um exemplo na Listagem 3. Para testar esse código adicione uma nova página e coloque um botão (ID=btnExcluir) depois clique duas vezes no mesmo e adicione o código.

Listagem 3: Excluindo Registros

Imports System.Data   
Imports System.Data.SqlClient 
"Imports System.Data.OleDb 

Public Class temp 

    Inherits System.Web.UI.Page 

    Private Sub Page_Load _ 

    (ByVal sender As System.Object, _ 

    ByVal e As System.EventArgs) Handles MyBase.Load 

    End Sub 

    Private Sub btnExcluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	      Handles btnExcluir.Click 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand

        conn.ConnectionString = _
	   "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn
        cmd.CommandText = "Delete [Order Details] where OrderID=10248"
        cmd.CommandType = CommandType.Text
        conn.Open()  

        Dim intRetorno As Int32
        intRetorno = Convert.ToInt32(cmd.ExecuteNonQuery) 

        If intRetorno > 0 Then
            Response.Write("Registro(s) Excluido(s):" + intRetorno.ToString)
        else
            Response.write ("Resgistro não excluido")
        End If  

        conn.Close()
        conn.Dispose() 

    End Sub 

End Class

Observando o código da Listagem 3 você deve está sentindo falta do DataReader, como estamos acessando o banco de dados para processar uma consulta SQL que não retorna nada o mesmo não é necessário nesse caso. O próprio Command já retorna um valor inteiro indicando quantas linhas foram afetadas pelo comando. Repita o mesmo processo da Listagem 3 para os outros Transacion-SQL (Insert e Update) e terá o resultado esperado. Agora fique atento à modelagem do banco, pois o mesmo vai impor e obrigar que tenha integridade nos campos, você não vai excluir um registro em uma tabela se ele está relacionado com outro em outra. Ou seja, primeiro você deve respeitar as regras do SGDB.

Agora vamos fazer um exemplo do DataBind que como já falamos é a capacidade do controle de ler automaticamente o retorno do banco de dados. Para isso insira uma nova página chamada de DataGridTeste.aspx, depois arraste um componente do tipo DataGrid (ID=dgConsulta) para a página conforme Figura 08 e clique no mesmo com botão direito depois escolha AutoFornat para definir um layout dentre os padrões já oferecidos e adicione o código da Listagem 4.

Inserido DataGrid e formatando Layout

Figura 11: Inserido DataGrid e formatando Layout

Listagem 4: Fazendo DataBind no DataGrid

Imports System.Data.SqlClient
Imports System.Data 

Public Class DataGridTeste 

    Inherits System.Web.UI.Page

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
           Handles MyBase.Load 

        If Not Page.IsPostBack Then
            carregaDG()
        End If 

    End Sub 

    Sub carregaDG()
        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim dr As SqlDataReader 

        conn.ConnectionString = _
	   "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn
        cmd.CommandText = "Select * from Products"
        cmd.CommandType = CommandType.Text
        conn.Open() 

        dr = cmd.ExecuteReader
        Me.dgConsulta.DataSource = dr
        Me.dgConsulta.DataBind() 
        conn.Close()
        dr.Close()
        conn.Dispose()
    End Sub 

End Class

Observando o código da Listagem 4 você verá apenas uma pequena novidade (Me.dgConsulta.DataSource = dr , Me.dgConsulta.DataBind()) nestas duas linhas estamos informando para o DataGrid que ele precisa ler esse DataReader e realizar o DataBind (Preenchimento automático dos dados). Efetue o build do código e verifique o resultado conforme Figura 09.

DataGrid carregado pelo DataBind

Figura 12: DataGrid carregado pelo DataBind

Até o momento, todos exemplos de acesso a dados apresentados são conectados ao banco de dados. Falando ainda da classe Command já utilizamos dois métodos (ExecuteReader, Executenoquery) vamos ver um outro exemplo com o método ExecuteEscalar, esse método é a forma de acesso mais rápido ao banco de dados, pois independente do retorno ocasionado pela consulta SQL ele somente vai ler uma linha, uma coluna . É recomendado para retorno de Stored Procedures ou o Count(*) do Select. Confira um exemplo na Listagem 5.

Listagem 5: Utilizando método ExecuteScalar da classe Command

Imports System.Data.SqlClient
Imports System.Data 

Public Class DataGridTeste 

    Inherits System.Web.UI.Page  

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	      Handles Button1.Click 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand  

        conn.ConnectionString = _
	   "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn
        cmd.CommandText = "Select count(*) Total from Products"
        cmd.CommandType = CommandType.Text
        conn.Open()  

        Dim intRetorno As Int32 

        intRetorno = Convert.ToInt32(cmd.ExecuteScalar)
        Response.Write("Total produtos:" + intRetorno.ToString)
        conn.Close()
        conn.Dispose() 

    End Sub 

End Class

O código da Listagem 5 está utilizando o método ExcuteScalar para ler o retorno do count(*) informado pela consulta SQL.Para tornar seu código mais claro você pode utilizar parâmetros em conjunto com as consultas SQL, essa facilidade é permitida por meio da class SqlParameter ou OleDbParameter veja o exemplo na Listagem 5. Nesta listagem vamos modificar a consulta sql (Select * from Products where ProductID = 1) para aceitar parâmetros. Como o exemplo é similar a qualquer outro estarei apenas demonstrando no código.

Listagem 6: Utilizando parâmetros em conjunto com consulta SQL

Imports System.Data.SqlClient
Imports System.Data 

Public Class DataGridTeste 

    Inherits System.Web.UI.Page  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		      Handles MyBase.Load 

        If Not Page.IsPostBack Then
            carregaDG()
        End If 


    End Sub 

    Sub carregaDG() 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim dr As SqlDataReader
        conn.ConnectionString = _
	   "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn 

        "cmd.CommandText = "Select *  from Products where ProductID=1"
        cmd.CommandText = "Select *  from Products where ProductID=@ID"
        cmd.CommandType = CommandType.Text
        cmd.Parameters.Clear()
        cmd.Parameters.Add(New SqlParameter("@ID", SqlDbType.Int)).Value = 1
        conn.Open() 

        dr = cmd.ExecuteReader
        Me.dgConsulta.DataSource = dr
        Me.dgConsulta.DataBind() 

        conn.Close() 

        dr.Close() 

        conn.Dispose() 

    End Sub 

End Class

Observando o código da Listagem 6 veja que o código do produto que estava sendo informado na consulta passou a ser informado externamente. Em consulta SQL essa modificação não é requerida, porém para Stored Procedures (Procedimentos armazenados) é fundamental, dai uma chance de ir treinando.

Nosso próximo objetivo será executar uma Stored Procedure (procedimento armazenado). É um Transact-SQL que já fica salvo no servidor de banco de dados, com isso o banco consegue se preparar pra executar mais rapidamente esse código, por isso é muito recomendado a criação desses procedimentos dentro do SGDB. O SQL Server já vem com um procedimento padrão chamado de sp_who2 que retorna todos usuários conectados no SGDB é muito importante para gerenciar que aplicação está utilizando SGDB no momento. Essa procedure não requer parâmetros. Veja o exemplo na Listagem 7 que está carregando um DataGrid com retorno da procedure.

Listagem 7: Utilizando Store Proceure sp_who2

Imports System.Data.SqlClient
Imports System.Data 

Public Class DataGridTeste 

    Inherits System.Web.UI.Page  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		   Handles MyBase.Load 

        If Not Page.IsPostBack Then
            carregaDG()
        End If 

    End Sub 

    Sub carregaDG() 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim dr As SqlDataReader 

        conn.ConnectionString = "Data Source=localHost; User ID=sa; Password=;
        Initial Catalog=Northwind;"                
        cmd.Connection = conn
        cmd.CommandText = "sp_who2"
        cmd.CommandType = CommandType.StoredProcedure

        conn.Open()
        dr = cmd.ExecuteReader
        Me.dgConsulta.DataSource = dr
        Me.dgConsulta.DataBind()

        conn.Close()
        dr.Close()
        conn.Dispose() 

    End Sub 

End Class
Como neste momento você já conhece muito bem o código da Listagem 7, a única diferença que vai encontrar é nas linhas (cmd.CommandText = "sp_who2" e cmd.CommandType = CommandType.StoredProcedure) que informa a StoreProcedure sp_who2, confira o retorno da mesma na Figura 10. Retorno da Stored Procedure sp_who2

Figura 13: Retorno da Stored Procedure sp_who2

Como você ficou curioso para ver como se utiliza uma Stored Procedure com parâmetros vamos ao código da Listagem 8. Nesse código vamos utilizar a Stored Proceure SalesByCategory presente no DataBase NorthWind, portanto não precisamos nos preocupar com sua criação até porque não é o propósito desse artigo. Essa procedure recebe dois parâmetros de entrada para você saber que parâmetros a procedure necessita utilize o comando sp_help nome_da_procedure pelo utilitário Query Analyzer conforme Figura 11.

Obtendo informações da procedure SalesByCategory

Figura 14: Obtendo informações da procedure SalesByCategory

Listagem 8: Utilizando Stored Procedure SalesByCategory com parâmetro.

Imports System.Data.SqlClient
Imports System.Data 


Public Class DataGridTeste 

    Inherits System.Web.UI.Page 

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		      Handles MyBase.Load 

        If Not Page.IsPostBack Then
            carregaDG()
        End If 

    End Sub 

    Sub carregaDG() 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim dr As SqlDataReader 

        conn.ConnectionString = _
	   "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn  

        cmd.CommandText = "SalesByCategory"
        cmd.CommandType = CommandType.StoredProcedure
        cmd.Parameters.Clear()
        cmd.Parameters.Add(New SqlParameter("@CategoryName", SqlDbType.VarChar)).Value = "Beverages"
        cmd.Parameters.Add(New SqlParameter("@OrdYear", SqlDbType.VarChar)).Value = "200"  

        conn.Open() 

        dr = cmd.ExecuteReader 

        Me.dgConsulta.DataSource = dr 

        Me.dgConsulta.DataBind() 

        conn.Close() 

        dr.Close() 

        conn.Dispose() 

    End Sub 

End Class

Como você acabou de ver na Listagem 7 o código é parecido com o feito na Listagem 6 pode ser conferido na Figura 12.

Retorno da StordeProcedure

Figura 15: Retorno da StordeProcedure (SalesByCategory)

Conforme visto durante todos os exemplos de DataReader sua implementação é muito simples, basta mesmo seguir os passos apontados nesse artigo e usufruir de todas as vantagens do ADO.NET que já traz dentro de duas classes toda comunicação das APIs de cada SGDB. Deixando para o programador, simples comandos com ótimos resultados.

Utilizando o DataSet

O DataSet é uma das grandes novidades oferecidas pelo novo ADO.NET. Ele é uma estrutura de dados totalmente desconectada do banco de dados, basea-se em xml e armazenada na memória todos os dados recebidos da base de dados. Garantindo com isso toda uma manipulação fora do banco de dados para depois devolver os dados modificados. O DataSet se assemelha muito com um banco de dados pois ele armazena as informações em uma estrutura semelhante, sendo que dentro você pode criar varias tabelas, e dentro das tabelas você inclui as colunas e os dados. Ainda dentro do mesmo você pode criar relacionamentos entre as tabelas, utilizar tabelas de origem de dados diferentes, percorrer qualquer um dos registros a qualquer momento e inclusive transportar essa estrutura de um ponto para outro utilizando web services (Componentes web baseados em xml e soap). Verifique um modelo simplificado na Figura 13 e Figura 14.

Visão simplificada Data Set 1

Figura 16: Visão simplificada Data Set 1

Visão simplificada do Data Set 2

Figura 17: Visão simplificada do Data Set 2

Para utilizart o Data Set vamos precisar seguir os passos que fizemos para o DataReader com algumas modificações conforme os tópicos abaixo:

  1. Connection - Abre e fecha conexão, necessita de uma string de acesso conforme Tabela 04.
  2. Command - Vai processar seu comando Transaction-SQL no SGDB.
  3. DataAdapter - Obtém dados do SGDB e preenche o DataSet
  4. DataSet - Estrutura de dados xml, será preenchida pelo DataAdapter

Como você já utilizou o DataReader o DataSet também é de simples utilização, vamos fazer o mesmo exemplo utilizando uma página feita em asp e convertendo para asp.net utilizando ADO.NET e DataSet.

Listagem 9: Conexão com banco

<%
"Arquivo: Teste.asp
set conn = server.createobject("adodb.connection") 
Conn.Open "Provider=SQLOLEDB.1;Data Source=localhost;Initial Catalog=Northwind;User ID=sa;Password=;"
sql="select * from Products"
set rs=Conn.Execute(SQL)
do while not rs.eof
response.write cstr(rs.fields("ProductID"))+"<BR>"
response.write cstr(rs.fields("ProductName"))+"<hr>"
rs.movenext
loop
Conn.Close
rs.Close
set rs=nothing
set conn=nothing
%>

Agora adicione uma nova página webform ao seu projeto com o nome de testedataset.aspx, depois efetue dois cliques e adicione o código da Listagem 10.

Listagem 10: Código para testedataset.aspx

Imports System.Data
"Imports System.Data.SqlClient
"Imports System.Data.OleDb 

Public Class testedataset 

    Inherits System.Web.UI.Page  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

        Dim conn As New SqlConnection "Criando objeto Connection 
        Dim cmd As New SqlCommand "Criando objeto Command
        Dim da As New SqlDataAdapter "Crianda DataAdapeter
        Dim ds As New DataSet  "Criando objeto DataSet 

        conn.ConnectionString = _
	   "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn
        cmd.CommandText = "Select * from Products"
        cmd.CommandType = CommandType.Text
        da.SelectCommand = cmd
        da.Fill(ds, "Produtos") "Preenchendo DataSet
 
        "Desconectado do banco de dados
        conn.Dispose()
        da.Dispose()  

        "Lendo DataSet
        "Neste ponto não estamos mais conectados ao banco de dados  

        Dim intI As Int32

        For intI = 0 To ds.Tables(0).Rows.Count - 1
            Response.Write(Convert.ToString(ds.Tables(0).Rows(intI)(0)) + "<BR>")
            Response.Write(Convert.ToString(ds.Tables(0).Rows(intI)(1)) + "<HR>")
        Next 

    End Sub  

End Class

Observando o código acima vamos encontrar muita semelhança com o primeiro exemplo de DataReader apresentado na Listagem 2, a principal diferença que você vai encontrar é que não estamos chamando o método Conn.Open pois isso está sendo feito pelo DataAdapter que se encarrega de acessar os dados e preencher o DataSet para que possa ser trabalhando de forma desconectada. Porém se você explicitamente utilizar o Conn.Open terá que efetuar o Conn.Close. Logo em seguida no final no loop que estamos realizando colocamos para varrer até a ultima linha do DataSet, de forma que obtemos essa quantidade pelo Rown.Count. Neste exemplo estamos fazendo referências a todos itens do DataSet utilizando "Indices" no lugar de colocar o nome das colunas e tabelas.

Conforme já afirmamos anteriormente é possível criar um DataSet utilizando a IDE do Visual Studio para que de forma visual possamos estabelecer o acesso ao SGDB. Para montarmos esse exemplo siga os passos abaixo:

  1. Adicione um novo webform chamado de testeide.aspx
  2. Acione o Server Explorer conforme Figura 15. Utilizando o menu view>server explorer ou CTRL+ALT+S
Server Explorer

Figura 18: Server Explorer

O Server Explorer é um novo utilitário oferecido pela IDE do Visual Studio que permite a gerência do banco de dados, ele funciona praticamente com todos os banco de dados compatíveis com OLEDB. É uma ferramenta muito útil, pois no próprio Visual Studio você tem recursos oferecidos pelo Enterprise Mananger (Figura 2) do SQL Server. Você pode criar tabelas, colunas, modificar e exibir dados conforme Figura 16.

Após esse breve resumo sobre o Server Explorer, clique na tabela products e arraste diretamente para o formulário, automaticamente será criado um SqlConnection e um SqlDataAdapter conforme Figura 17.

SqlConnection e SqlDataAdapter criados pelo IDE

Figura 19: SqlConnection e SqlDataAdapter criados pelo IDE

O próximo passo agora é criar o DataSet, para isso basta criar no botão direito do SqlDataAdapter e escolher a opção "Generate DataSet" conforme Figura 18 e Figura 19.

Criando DataSet pelo IDE

Figura 20: Criando DataSet pelo IDE

Criando DataSet pelo IDE

Figura 21: Criando DataSet pelo IDE

Concluído esse passo você já criou o DataSet e ele já deve está aparecendo na IDE do Visual Studio. A grande novidade do .NET é que todo o código para criar todos passos que seguimos até o momento está visível, basta efetuar dois cliques no formulário e ir a área de código depois clique na Região "Web Form Designer Generated Code", com isso você vai acompanhar todos os passos que o Visual Studio está fazendo até criar seu DataSet. Todo procedimento que estamos fazendo aqui é similar ao da Listagem 8 com a diferença que estamos utilizando a interface visual para criar. Veja agora a mesma representação na Listagem 11 que difere da Listagem 10 por não precisar criar os objetos de acesso a dados sendo que já foi criado pelo IDE.

Listagem 11: Utilizando IDE do Visual Studio para gerar

DataSet</p>
Public Class testeide 
    Inherits System.Web.UI.Page
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		      Handles MyBase.Load 

        "Opcionalmente estou trocando a String de conexão porque
        "o padrão do IDE é Windows Integrado, e a maquina precisa está
        "corretamente configurada.

        Me.SqlConnection1.ConnectionString = _
	   "Data Source=localhost;user id=sa;Password=;Initial  catalog=Northwind;" 

        Me.SqlDataAdapter1.Fill(Me.DsTeste1)

        Dim intI As Int32
        For intI = 0 To DsTeste1.Tables(0).Rows.Count - 1
            Response.Write(Convert.ToString(DsTeste1.Tables(0).Rows(intI)(0)) + "<BR>")
            Response.Write(Convert.ToString(DsTeste1.Tables(0).Rows(intI)(1)) + "<HR>")
        Next  

    End Sub
End Class

Observado as diferenças entre os códigos, comente o código na página (testeide.aspx) e arraste para página um componente DataGrid (ID=dgConsulta) alterando seu ID conforme especificado. Depois altere as propriedades DataSource e DataMember confome Figura 20. Observe que está mudando na janela de propriedades, isso está sendo possível porque você criou o DataSet pelo IDE. Depois mude a aparência do DataGrid clicando com botão direito em cima do mesmo e escolhendo AutoFormat.

Configurando DataGrid

Figura 22: Configurando DataGrid

Configurado o DataGrid, vamos ao código na Listagem 12 para ativar o funcionamento.

Listagem 12: Carregando DataGrid

Public Class testeide 
    Inherits System.Web.UI.Page  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		       Handles MyBase.Load 

        Me.SqlConnection1.ConnectionString = _
	    "Data Source=localhost;user id=sa;Password=;Initial Catalog=Northwind;"
        Me.SqlDataAdapter1.Fill(Me.DsTeste1)
        Me.dgConsulta.DataBind()

    End Sub
End Class

Após adicionar o código efetue o Build e teste vai notar que apenas com essas linhas de código você vai carregar os dados no DataGrid conforme Figura 21.

DataGrid usando IDE

Figura 23: DataGrid usando IDE

A vantagem de se utilizar o IDE é poder realizar as configurações de acesso ao banco de dados pela janela de propriedades e reduzir a quantidade de código a ser digitado. Não implica na redução de código gerado, pois o Visual Studio gera uma quantidade enorme de código para permitir essas facilidades.

No entanto nunca utilizo esse recurso da IDE, pois considero muito fácil o acesso utilizando o código direto e fica mais claro o entendimento. E se você for seguir o padrão patterns & pratices da Microsoft, toda implementação do Data Access Block é feita utilizando código. Fica a sua escolha, escolher o caminho.

Resumindo o que já fizemos até esse momento, nós carregamos um DataSet com os dados de um SGDB. Mas sabemos que o DataSet contém DataTable que contém DataColumn e DataRow conforme já visto na Figura 13 e na Figura 14. Vamos agora criar um DataTable totalmente via código e inserir dados via código. Para isso insira um novo webform (datatablecodigo.aspx) e depois adicione o código da Listagem 13.

Listagem 13: Criando DataTable usando código

Public Class DataTableCodigo 
    Inherits System.Web.UI.Page 

     Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		       Handles MyBase.Load 

        If Not Me.Page.IsPostBack Then
            carrega()
        End If 

    End Sub 

    Sub carrega() 

        Dim dt As New DataTable  

        "Criando Coluna Coódigo
        "com auto numeração. 

        Dim dc As New DataColumn
        dc = New DataColumn
        dc.DataType = System.Type.GetType("System.Int32")
        dc.ColumnName = "Codigo"
        dc.ReadOnly = True "Não pode ser alterado
        dc.Unique = True "Não repete
        dc.AutoIncrement = True " Define AutoIncremento
        dc.AllowDBNull = False "Não aceitar nulos
        dt.Columns.Add(dc) "Adicionando Coluna 

        "Criando Coluna Nome
        dt.Columns.Add(New DataColumn("Nome", GetType(String)))
        "Criando Coluna Email
        dt.Columns.Add(New DataColumn("Email", GetType(String)))  

        "----- Fim Criação DataTable ---------------  

        "Adicionando Linhas  

        Dim dr As DataRow = dt.NewRow
        dr("Nome") = "Ramon Durães"
        dr("Email") = "ramonduraes@mutex.com.br"
        dt.Rows.Add(dr)
        dr = dt.NewRow
        dr(1) = "Mike Silver"
        dr(2) = "mk@msspace.com"
        dt.Rows.Add(dr)  

        "////////////////////////////////
        "Criando DataGrid Dinamicamente
        "e adicionando a página
        "//////////////////////////////// 

        Dim dg As New DataGrid
        dg.DataSource = dt.DefaultView
        dg.DataBind()
        Me.Page.FindControl("Form1").Controls.Add(dg) 

    End Sub 

End Class

Após adicionar o código efetue o Build e teste essa página, o resultado deve ser similar a Figura 22. Neste exemplo estamos criando um DataTable, adicionando as colunas, e depois as linhas. Tudo isso feito sem nenhum acesso ao SGDB. O detalhe importante é a coluna "Codigo" que foi criada como auto-numeração e o DataTable automaticamente adiciona o numero a coluna. Observe que nesse exemplo não utilizamos DataSet.

DataTable Via código

Figura 24: DataTable Via código

Digamos agora que você queira ver o conteúdo do DataTable que está armazenado na memória, então vamos salvar o conteúdo do mesmo em um arquivo XML conforme Listagem 14. Essa Listagem é semelhante a anterior e poderia ser qualquer outra que se tenha um DataSet pois o mesmo que esta no formato de XML, para esse caso criamos um DataSet e armazenamos o DataTable dentro. O Xml gerado é mostrado na Figura 23.

Listagem 14: Gerando arquivo xml apartir de um DataSet

Public Class DataTableCodigo 
    Inherits System.Web.UI.Page 

     Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		       Handles MyBase.Load 

        If Not Me.Page.IsPostBack Then
            carrega()
        End If 

    End Sub 

    Sub carrega() 

        Dim dt As New DataTable  

        "Criando Coluna Coódigo
        "com auto numeração. 

        Dim dc As New DataColumn
        dc = New DataColumn
        dc.DataType = System.Type.GetType("System.Int32")
        dc.ColumnName = "Codigo"
        dc.ReadOnly = True "Não pode ser alterado
        dc.Unique = True "Não repete
        dc.AutoIncrement = True " Define AutoIncremento
        dc.AllowDBNull = False "Não aceitar nulos
        dt.Columns.Add(dc) "Adicionando Coluna 

        "Criando Coluna Nome
        dt.Columns.Add(New DataColumn("Nome", GetType(String)))
        "Criando Coluna Email
        dt.Columns.Add(New DataColumn("Email", GetType(String)))  

        "----- Fim Criação DataTable ---------------  

        "Adicionando Linhas  

        Dim dr As DataRow = dt.NewRow
        dr("Nome") = "Ramon Durães"
        dr("Email") = "ramonduraes@mutex.com.br"
        dt.Rows.Add(dr)
        dr = dt.NewRow
        dr(1) = "Mike Silver"
        dr(2) = "mk@msspace.com"
        dt.Rows.Add(dr)  

        "////////////////////////////////
        "Criando DataGrid Dinamicamente
        "e adicionando a página
        "//////////////////////////////// 

        Dim dg As New DataGrid
        dg.DataSource = dt.DefaultView
        dg.DataBind()
        Me.Page.FindControl("Form1").Controls.Add(dg)  


        "////////////////////////////////
        "Criando XML
        "////////////////////////////////   


        Dim ds As New DataSet
        ds.Tables.add(DT)
        ds.WriteXml("C:\temp\datasetcodigo.xml")          

    End Sub 

End Class
XML Gerado pelo WriteXML

Figura 25: XML Gerado pelo WriteXML

O DataSet possui dois métodos importantes o WriteXML e o ReadXml, sendo usados para escrita e para leitura, por está no formato xml, DataSet pode ser transportado pela internet por meio de web services.

Vamos agora fazer o contrário, vamos carregar um DataSet a partir de um arquivo xml utilizando método ReadXML, para isso vamos criar um novo XML, então botão direito no projeto (solution explorer)>Add new item>XML conforme Figura 24, e dê o nome de demoxml.xml.

Criando arquivo xml

Figura 26: Criando arquivo xml

Depois digite o código xml conforme a Figura 25. Após adicionar essa parte, clique na opção Data logo no final e terá o resultado mostrado na Figura 26.

Adicionando registros

Figura 28: Adicionando registros

Você pode adicionar agora mais registros usando essa interface visual, após terminar clique novamente em xml e vai ver o código gerado. Após terminar insira um novo webform (datasetread.aspx) e adicione o código da Listagem 15.

Listagem 15: Carregando DataSet usando xml

Public Class datasetread 
    Inherits System.Web.UI.Page 

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

        Dim ds As New DataSet
        ds.ReadXml(Server.MapPath("demoxml.xml"))
        dgConsulta.DataSource = ds.Tables(0)
        dgConsulta.DataBind()
    End Sub

End Class

Após efetuar Build e testar o código teremos o resultado na Figura 27.

Lendo xml e carregando DataSet

Figura 29: Lendo xml e carregando DataSet

Conforme visto com poucas linhas já temos um DataSet que está sendo alimentado a partir de um arquivo XML. Vamos agora criar um DataGrid com páginação e utilizando um DataSet. Para iniciar adicione um novo WebForm (DataGridpágina.aspx), depois adicione um DataGrid (ID=dgConsulta) e formate com layout preferido, depois clique no mesmo com botão direito e escolha Property Builder>Paging e configure conforme a Figura 28. Feito isso efetue dois cliques na página e adicione o código de acordo com a Listagem 16.

Configurando DataGrid para páginação

Figura 30: Configurando DataGrid para páginação

Listagem 16:Paginando DataGrid com DataSet

Imports System.Data
Imports System.Data.SqlClient  
Public Class datagridpágina 

    Inherits System.Web.UI.Page  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		      Handles MyBase.Load 

        If Not Page.IsPostBack Then
            carregaDG()
        End If 

    End Sub 

    Sub carregaDG() 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim da As New SqlDataAdapter
        Dim ds As New DataSet 

        conn.ConnectionString = _
	    "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn
        cmd.CommandText = "Select * from Products"
        da.SelectCommand = cmd
        da.Fill(ds)  

        conn.Dispose()
        cmd.Dispose()
        da.Dispose()  

        Me.dgConsulta.DataSource = ds
        Me.dgConsulta.DataBind() 

    End Sub 

    Private Sub dgConsulta_PageIndexChanged(ByVal source As Object, _
	      ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) _
              Handles dgConsulta.PageIndexChanged 

       Me.dgConsulta.CurrentPageIndex = e.NewPageIndex
        carregaDG()
    End Sub 

End Class

Após adicionar o código e efetuar Build confira o resultado semelhante a Figura 29. Fique apenas atento ao evento PageIndexChanged do DataGrid pois é mesmo que é disparado quando se clica na mudança de página no DataGrid.

DataGrid com páginação

Figura 31: DataGrid com páginação

Falando sobre DataSet não podemos também de deixar de fazer um exemplo sobre DataView que um padrão de projeto Model-View, que permite a criação de visões dos dados recuperados, podendo filtrar, ordenar os dados que estão no DataTable/DataSet. Existe alguns casos que você não consegue mudar a ordem dos dados, como o retorno de uma procedure. Então você usa o DataView para mudar a ordem dos dados. Vamos agora aproveitar e fazer um exemplo que englobe duas coisas DataView e StoredProcedures. Para essa tarefa adiciona um novo webform (DataSetView.aspx), depois adicione um DataGrid (ID=dgConsulta) e adicicione o código da Listagem 17.

Listagem 17: Utilizando DataView

Imports System.Data
Imports System.Data.SqlClient 
Public Class datasetview 

    Inherits System.Web.UI.Page  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
		       Handles MyBase.Load
        carregaDG()
    End Sub 

  

    Sub carregaDG() 

        Dim conn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim da As New SqlDataAdapter
        Dim ds As New DataSet 

        conn.ConnectionString = _
	    "Data Source=localHost; User ID=sa; Password=;Initial Catalog= Northwind;"
        cmd.Connection = conn
        cmd.CommandText = "SalesByCategory"
        cmd.CommandType = CommandType.StoredProcedure
        cmd.Parameters.Clear()
        cmd.Parameters.Add(New SqlParameter("@CategoryName", SqlDbType.VarChar)).Value = "Beverages"
        cmd.Parameters.Add(New SqlParameter("@OrdYear", SqlDbType.VarChar)).Value = "2002" 

        da.SelectCommand = cmd
        da.Fill(ds)
        conn.Dispose()
        da.Dispose()
        cmd.Dispose() 

        "Utilizando DataView para ordenar 
        Dim dv As New DataView(ds.Tables(0))
        dv.Sort = "ProductName DESC"
        Me.DataGrid1.DataSource = dv
        Me.DataGrid1.DataBind() 

    End Sub 

End Class

Após adicionar o código e efetuar o Build confira na Figura 30, neste exemplo ordenamos pela coluna ProductName, isso dentro do DataView e não no banco de dados, até porque o retorno do mesmo é uma procedure. E estamos passando o DataView para o DataGrid e não o DataSet.

Exibindo DataView

Figura 32: Exibindo DataView

Conforme resultado na Figura 30, o retorno do banco de dados está ordenado.

Referências

BIPIN, Joshi (org). Profissional ADO.NET - Programando, Ed. Alta Books - Rio de Janeiro, 2002 patterns & practices , Ed. Microsoft - São Paulo,2003

Finalizando

Como vimos durante todo o artigo o ADO.NET é a mais recente evolução referente a acesso a dados. Trazendo atualmente grandes facilidades podendo ser conectado (DataReader) ou não ao SGDB (DataSet). Possui atualmente classes de acesso nativo ao SGDB, resultando em melhor desempenho e ainda se utiliza de todos recursos oferecidos pelo .NET Framework. Agora que você já conhece o ADO.NET dedique-se um tempo para aprofundar nesse assunto e sobre Web Services. Para uma melhor utilização do ADO.NET recomenda-se construir uma classe que encapsula todos comandos de acesso, exemplo feito no Data Access Block (http://msdn.microsoft.com/pratics)

O que você gostaria saber?

Aguardo seu comentário! Participe!!! Até próximo artigo! Você é de Salvador Bahia? Então participe do grupo de usuários .NET - http://www.mutex.com.br

Ramon Durães

Ramon Durães - Especialista em desenvolvimento de software e Microsoft Most Valuable Professional (MVP) em Visual Studio Team System. Realiza treinamentos de .NET Framework em empresas, consultoria em arquitetura de software e implantação de Visual Studio Team System. Palestrante nos principais eventos da Microsoft no Brasil (Tech-Ed 2005, Tech-Ed 2006, Tech-Ed 2007, Tech-Ed 2008, Tech-ED 2009), Microsoft Innovation Days 2007 (Salvador, Brasília, Recife, Goiânia, Natal, Maringá), Microsoft Innovation Days 2009 (Salvador) , Campus Party Brasil 2009 e eventos regionais relacionados a grupos de usuários e universidades. Conhecido autor de artigos para os principais portais de conteúdo e autor de 10 publicações eletrônicas em CD (Video-Aula) pela editora Linha de Código além dos livros "Desenvolvendo para web usando o Visual Studio 2008" e "Gerenciando projetos de software usando Visual Studio Team System" pela editora Brasport. Pode ser encontrado em seu blog http://www.ramonduraes.net e @ramonduraes no Twitter.