Clique aqui para ler este artigo em pdf
Clique aqui para ler todos os artigos desta edição
Treinamento em ASP.NET (Parte II)
por Renato Haddad
Vamos à segunda parte do treinamento em ASP.NET, na qual você aprenderá a manipular alguns dos controles utilizados com mais freqüência durante o acesso a banco de dados. Atualmente é normal que os dados fiquem armazenados em alguma fonte de dados, seja um banco de dados no SQL Server, Oracle, MS-Access, DB2 ou então, em arquivos XML e textos. No .NET, isso é completamente transparente, ou seja, não importa onde estejam os dados.
Na parte I, você aprendeu a criar uma solução. Então, abra a solução MSDNMag (criada na parte I) e adicione um novo formulário, (Add / Add Web Form) denominado BancoDados.aspx. Selecione o menu View / Toolbox ou pressione Ctrl + Alt + X para exibir a Toolbox. Monte um formulário semelhante ao da Figura 1, contendo os seguintes itens: uma tabela para alinhamento dos dados, um DropDownList, um RadioButtonList, três Buttons, um Label, um CheckBoxList e um DataGrid. Para inserir todos esses controles, clique neles e arraste-os no documento. Para digitar qualquer texto no documento, clique na devida posição do formulário e digite os respectivos textos: “Bando de Dados – ASP.NET”, “Categorias”, “Colunas:” e “Direção:”. Para formatar um texto, basta seleciona-lo e então aplicar as formatações existentes na barra de ferramentas.
Dica: Sempre que você quiser mudar de linha pressione ENTER ou SHIFT + ENTER. Existe uma diferença sutil no espaçamento, onde ENTER provoca um novo parágrafo e SHIFT + ENTER provoca uma quebra de linha. Não esqueça que para digitar no corpo do documento é necessário que a propriedade pageLayout de sua página esteja definida como FlowLayout.
Figura 1 – Design da página
Exiba a janela de propriedades (F4) e configure as propriedades dos controles de acordo com a Tabela 1: note que o AutoPostBack do dropColunas e do rdDirecao devem estar definidos como True, ou a página não será enviada ao servidor para o processamento. Essa propriedade provoca um Post na página, ou seja, ela submete a solicitação ao servidor.
DropDownList (ID) |
DropColunas |
AutoPostBack |
True |
Items (Collection) |
Crie uma lista de 1 a 5, tanto para Text como para Value |
RadioButtonList (ID) |
rdDirecao |
AutoPostBack |
True |
Items (Collection) |
Crie a seguinte lista: Horizontal e Vertical, tanto para Text como para Value |
CheckedBoxList (ID) |
CkCategorias |
Button1 (ID) |
BtnLimpa |
Text |
Limpa Todas |
Button2 (ID) |
BtnSeleciona |
Text |
Seleciona Todas |
Button3 (ID) |
btnPesquisar |
Text |
Pesquisa os produtos das categorias selecionadas |
Label1 (ID) |
lblProdutos |
Text |
Branco |
DataGrid1 (ID) |
|
Visible |
False |
Tabela 1 – Propriedades dos controles
Com relação ao DataGrid, você pode formatá-lo de acordo com as opções de formato pré-definidas. Para isso, pressione o botão direito sobre o controle e selecione AutoFormat. Escolha um formato de acordo com a sua necessidade e observe que as propriedades do estilo serão configuradas automaticamente.
O banco de dados usado como exemplo é o Northwind, que está instalado no SQL Server. O funcionamento se dará da seguinte forma: na primeira vez que a página for carregada, o controle ckCategorias será preenchido com todas as categorias existentes na tabela Categories do banco de dados. Com isso, o internauta poderá selecionar qualquer categoria existente neste controle. Quando você pressionar o botão btnPesquisar, serão exibidos no gridProdutos todos os produtos referentes às categorias selecionadas. Os demais controles existem para que possamos explorar a parte de design interativo com os internautas, ou seja, você pode criar uma página para que o internauta a configure de acordo com as opções selecionadas. Esse processo é possível porque os controles permitem atribuir propriedades em tempo de execução, dispensando completamente a edição manual do design. Esse é um dos pontos fortes do ASP.NET.
Agora que você já conhece o design da página e como deverá funcionar, o próximo passo será digitar os códigos. Para isso, pressione F7 ou View / Code. Como vamos acessar um banco de dados SQL Server, digite na primeira linha a referência da classe do SQL Server. A classe SqlClient foi criada especialmente para o SQL Server versão 7.0 ou superior. Nos outros bancos de dados, você pode usar o OleDb.
Imports System.Data.SqlClient
Como iremos abrir o banco de dados em dois lugares, para facilitar a declaração da conexão, declare a variável conexão antes do evento Page_Load. Essa variável é do tipo String e contém o nome do banco de dados (Database), o nome do servidor (Server) e o usuário (User ID) de acordo com suas especificações da instalação do SQL Server na sua máquina. Caso necessite, declare a Password e os demais parâmetros da conexão. É importante ressaltar que todos os parâmetros declarados na conexão dependem de como você fez a sua instalação do SQL Server, os usuários existentes, as senhas e se tem ou não segurança integrada. Caso você execute a página e ocorra um erro de login ou conexão, verifique estes itens para que o código possa acessar o banco de dados Northwind.
Dim conexao As String = "Database=Northwind;Server=NomeServidor;user id=sa"
Digite o código no evento Page_Load (Listagem 1) para preencher o controle ckCategorias com todas as categorias existentes no banco de dados. Vale dizer que esse evento será executado todas as vezes que a página for carregada. No entanto, as categorias não mudam, e a pergunta é: por que então carregar todas as vezes que a página for executada? Realmente, não há a menor razão para isso e, desse modo, é possível verificar este fato através do Page.IsPostBack, ou seja, tudo o que estiver dentro deste bloco será executado apenas na primeira vez que a página for carregada. O restante da explicação está em cada uma das linhas da Listagem 1.
Listagem 1. Código do evento Page_Load
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Verifica se foi dado algum Post na página
If Not Page.IsPostBack Then
'Este código é executado apenas na primeira vez
'que a página é carregada, depois nunca mais!!!
'Declara a conexão
Dim conn As SqlConnection
'Define a string SQL
Dim sql As String = "SELECT CategoryID, CategoryName FROM Categories ORDER BY CategoryName"
'Declara o Adapter e o DataSet
Dim da As SqlDataAdapter
Dim ds As DataSet
'Monta a estrutura de erro
Try
'Instancia e abre a conexão usando a variável
'conexão declarada anteriormente
conn = New SqlConnection(conexao)
conn.Open()
'Instancia o Adapter contendo o SQL e a conexão
da = New SqlDataAdapter(sql, conn)
ds = New DataSet
'Monta uma tabela na memória denominada categorias
'contida dentro do Dataset ds
da.Fill(ds, "categorias")
'Configura as propriedades do checkBoxList
With ckCategorias
'Define que campo será exibido
.DataTextField = "CategoryName"
'Define que campo será armazenado
.DataValueField = "CategoryID"
'Define a origem do controle que é a tabela
'categorias que está na memória
.DataSource = ds.Tables("categorias").DefaultView
'Preenche o controle
.DataBind()
End With
'Caso ocorra ou não um erro, fecha a conexão
Finally
conn.Close()
End Try
End If
End Sub
Mas o que é um DataSet (usado no código da listagem 1)? DataSet é uma representação de uma ou mais tabelas na memória (contendo os métodos Select, Insert, Delete e Update) e é possível inclusive estabelecer relacionamentos entre elas. Isso significa dizer que podemos ter um DataSet contendo diversas tabelas.
Pelo fato de essa representação ser feita na memória, tudo é mais rápido. A grande característica do ADO.NET é trabalhar com dados desconectados, ou seja, todas as alterações são feitas na memória até que você as efetive no banco de dados.
Voltando ao exemplo: como todas as categorias estão listadas e dispõem de um checkbox para cada categoria, vamos facilitar a vida do internauta. Caso o internauta queira selecionar todas as categorias existentes, para que ele não precise clicar em cada categoria, podemos montar um código que faça isso automaticamente. A mesma idéia serve para desmarcar todas as categorias selecionadas. O código da Listagem 2 deverá ser implementado para os botões btnLimpa e btnSeleciona, portanto, dê um duplo clique em cada botão e digite o código que chama a rotina ChecaCategorias passando como parâmetro o True ou False. Esta rotina irá percorrer todos os checkbox do controle ckCategorias e atribui o True ou False para cada checkbox existente.
Listagem 2. Código para desmarcar ou selecionar todas as categorias
Private Sub btnLimpa_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLimpa.Click
ChecaCategorias(False)
End Sub
Private Sub btnSeleciona_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSeleciona.Click
ChecaCategorias(True)
End Sub
Private Sub ChecaCategorias(ByVal checa As Boolean)
'Declara um objeto do tipo ListItem
Dim objItem As ListItem
'Monta um looping para varrer todas as categorias
For Each objItem In ckCategorias.Items
'Para cada item atribui o conteúdo da variável
'checa se pode ser True/False
objItem.Selected = checa
Next
'Oculta os controles
gridProdutos.Visible = False
lblProdutos.Visible = False
End Sub
Para configurar as propriedades do ckCategorias em tempo de execução, é possível criar duas possibilidades: primeiro, configurar o número de colunas que serão exibidas. Para isso, dê um duplo clique no controle dropColunas e digite o código a seguir, que atribui à propriedade RepeatColumns o número de colunas selecionadas no DropColunas. Só um lembrete para quem já fez isso em ASP, PHP ou qualquer outro Script: veja como é fácil no ASP.NET, é apenas uma linha!
Private Sub dropColunas_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dropColunas.SelectedIndexChanged
ckCategorias.RepeatColumns = dropColunas.SelectedValue
End Sub
A segunda possibilidade é escolher a direção em que os dados serão exibidos: horizontal ou vertical. Para isso, dê um duplo clique no controle rdDirecao e digite o código que verifica qual foi a opção selecionada. Observe que, para isso, basta configurar a propriedade RepeatDirection. Mais um lembrete: será que é tão fácil assim em outras linguagens? Veja o ganho de produtividade.
Private Sub rdDirecao_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rdDirecao.SelectedIndexChanged
If rdDirecao.SelectedValue = "Horizontal" Then
ckCategorias.RepeatDirection = RepeatDirection.Horizontal
Else
ckCategorias.RepeatDirection = RepeatDirection.Vertical
End If
End Sub
A grande facilidade do ASP.NET é demonstrada aqui. Após selecionar as categorias, você precisa montar o DataGrid com todos os produtos, de acordo com as respectivas categorias selecionadas. A construção desse código é relativamente simples porque basta você aplicar um filtro à cláusula Where do SQL. No entanto, como o Internauta pode selecionar uma ou todas as categorias, o filtro precisará ser montado de forma que o looping percorra todos os itens do ckCategorias e verifique quais estão selecionados. Para cada item selecionado, é concatenada uma variável que contém o respectivo ID da categoria para executar o DataReader com a string SQL.
Quando usar um DataReader? Use o DataReader sempre que precisar ler uma fonte de dados; o DataReader é do tipo Forward Only, ou seja, você não consegue navegar em registros anteriores. Em termos de performance, um DataReader é muito mais rápido que um DataAdapter. A desvantagem é que você não conseguirá aplicar paginação em um DataGrid se este tiver sido preenchido com um DataReader, como é o caso deste exemplo.
Você irá notar que, na concatenação de strings, estou usando a classe System.Text.StringBuilder. Sempre que você precisar concatenar strings, opte pelo StringBuilder. Ele é infinitamente mais rápido que outras formas de concatenação, por exemplo, variável = variável + conteúdo ou variável += conteúdo ou variável = variável & conteúdo.
Private Sub btnPesquisar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPesquisar.Click
'Define a conexão, o Command, o DataReader e a string SQL
Dim conn As New SqlConnection(conexao)
Dim cmd As New SqlCommand
Dim Reader As SqlDataReader
Dim sql As New System.Text.StringBuilder
sql.Append("Select ProductName, UnitsInStock, UnitPrice FROM Products ")
'Como esta condição deverá ser montada em tempo de execução, pois vc
'não sabe quais itens o internauta irá selecionar, é preciso montar um
'looping para varrer todos os itens do CheckBoxList e, caso esteja
'selecionado, capturar o valor e adicioná-lo à string da cláusula Where do SQL
Dim condicao As New System.Text.StringBuilder
condicao.Append(" Where CategoryID IN (")
Dim ItemSelecionado As Boolean = False
For contador As Integer = 0 To ckCategorias.Items.Count - 1
'Verifica se o item atual está selecionado
If ckCategorias.Items(contador).Selected Then
ItemSelecionado = True
'Caso esteja, captura o valor e o armazena na variável condicao
condicao.Append(ckCategorias.Items(contador).Value + ", ")
End If
Next
'Como condicao é uma variável que poderá conter diversos itens, a string
'SQL requer que todos os itens estejam entre parênteses, portanto,
'esta linha adiciona o fecha parênteses à condicao
condicao.Append(")")
'Verifique que no looping cada item selecionado
'é inserido na variável condição seguido do
'respectivo separador de items (vírgula).
'No entanto, para arrumar a sintaxe do SQL,
'é preciso substituir ", )" por ")"
'No final, basta concatenar as duas variáveis
condicao = condicao.Replace(", )", ")")
sql.Append(condicao)
'Abre a conexão, monta o Command e executa o DataReader
conn.Open()
cmd = New SqlCommand(sql.ToString(), conn)
If ItemSelecionado Then
Reader = cmd.ExecuteReader()
'Exibe o DataGrid de produtos e o Label
gridProdutos.Visible = True
lblProdutos.Visible = True
'Define a origem do DataGrid
gridProdutos.DataSource = Reader
'Preenche o DataGrid
gridProdutos.DataBind()
'Exibe um texto contendo o número de produtos do DataGrid
lblProdutos.Text = "Existem " + gridProdutos.Items.Count.ToString() + " produtos."
'Fecha o DataReader e a conexão
Reader.Close()
End If
conn.Close()
End Sub
Após digitar todo o código, abra o Solution Explorer, clique com o botão direito sobre o BancoDados.aspx e selecione Set As Start Page. Compile e execute no navegador (Ctrl + F5) para ver o resultado. A Figura 2 exibe o DataGrid e todos os 52 produtos das categorias selecionadas.
Figura 2 – Execução da página
Conclusões
O ASP.NET nos permite interagir com o internauta de forma simples e objetiva com apenas algumas linhas de programação, personalizando a exibição do conteúdo da página para o internauta. Quanto ao acesso a fontes de dados, use e abuse das classes e controles de que o ASP.NET dispõe; afinal, programar para Web está cada vez mais simples, fácil e produtivo. “No stress, think .NET”.
Referências:
http://www.asp.net
http://www.gotdotnet.com
http://www.codeproject.com
http://www.linhadecodigo.com.br