Desenvolvimento - ADO.NET

Consulta a BD no .NET: Parte 2, WinForms

Na primeira parte deste artigo discutimos um pouco da arquitetura de acesso a banco de dados ADO.NET e seu uso em páginas ASP.NET...

por Mauro Sant'Anna



Na primeira parte deste artigo discutimos um pouco da arquitetura de acesso a banco de dados ADO.NET e seu uso em páginas ASP.NET.

Nesta segunda parte veremos como exibir consultas em aplicativos "WinForms" (não-Web) e também discutir alguns outros componentes importantes do ADO.NET como DataTable e DataRow. Usaremos o Visual Studio.NET Beta1.

Abstraindo uma tabela

Normalmente pensamos em uma "tabela" como algo exclusivamente amarrado a um banco de dados físico. O ADO.NET define uma tabela no componente DataTable que não está necessariamente ligada a tabelas físicas.

Um DataTable contém basicamente as seguintes informações:

  • "Estrutura" da tabela, essencialmente a quantidade, nomes e tipos das "colunas" (ou "campos");
  • Uma coleção de "linhas" (ou "registros") contendo os dados e seguindo a mesma estrutura da tabela.

A coleção de linhas é na verdade uma coleção de componentes DataRow.

Observe que um componente DataTable é perfeitamente definido sem que tenhamos que fazer acesso a bancos de dados. Podemos muito bem criar uma "tabela em memória" que atende a estas características. É exatamente isso que vamos fazer no exemplo seguinte.

Tabela em Memória

Crie um novo aplicativo "WinForms" na linguagem C# pedindo "File | New Project":

Criando novo projeto

Figura 1: Criando novo projeto

Adicione um Button e um DataGrid:, ambos a partir da página "Win Forms" do ToolBox:

Layout do form

Figura 2: Layout do form

Dê um clique duplo no botão e acrescente o seguinte código:

Listagem 1: Listando os dados

 // Cria uma nova tabela
DataTable Tbl = new DataTable();
// Adiciona os nomes e tipos das colunas
Tbl.Columns.Add("Número", typeof(double));
Tbl.Columns.Add("Quadrado", typeof(double));
Tbl.Columns.Add("Cubo", typeof(double));
// Prenche os dados dentro de um loop
for (int i = 1; i <= 10; i++) {
// Cria uma nova linha
DataRow Linha = Tbl.NewRow();
// Coloca os dados em cada uma das colunas desta linha
Linha[0] = i;
Linha[1] = i * i;
Linha[2] = i * i * i;
// Adiciona a linha na tabela
Tbl.Rows.Add(Linha);
}
// Exibe a tabela no DataGrid
dataGrid1.DataSource = Tbl;
// Muda o alinhamento no grid
dataGrid1.GridColumns[0].Alignment = HorizontalAlignment.Right;
dataGrid1.GridColumns[1].Alignment = HorizontalAlignment.Right;
dataGrid1.GridColumns[2].Alignment = HorizontalAlignment.Right;

Observe que este código cria uma tabela, define a sua estrutura e depois preenche a tabela, tudo em memória. Podemos exibir a tabela em um componente DataGrid. Veja o programa rodando:

Dados listados

Figura 3: Dados listados

Consulta a bancos de dados

Evidentemente podemos criar componentes DataTable para conter resultados a consultas de bancos de dados. Adicione ao projeto acima um outro Button e um componente ADOConnection. Ajuste a propriedade ConnectionString para acessar o banco de dados "Northwind". Veja a primeira parte deste artigo em caso de dúvidas:

Novo layout do form

Figura 4: Novo layout do form

Vamos acrescentar código para acessar o banco de dados e exibir o resultado no DataGrid no evento Click do botão:

Listagem 2: Consulta ao banco

// Copia o conteúdo de um DataReader em um DataTable
DataTable ConvDeDataReader(ADODataReader DR) {
// Cria um objeto DataTable para conter os resultados
DataTable Tbl = new DataTable();
// Ajusta nome das colunas do DataTable
for(int i = 0; i < DR.FieldCount; i++) {
Tbl.Columns.Add(DR.GetName(i));
}
// Cria array para conter os valores da linha
object[] Linha = new object[DR.FieldCount];
// Lê todos os registros
while (DR.Read()) {
// Pega valores do registro corrente
DR.GetValues(Linha);
// Adiciona registro ao objeto DataTable
Tbl.Rows.Add(Linha);
}
return Tbl;
}

protected void button2_Click (object sender, System.EventArgs e)
{
// Abre a conexão
adoConnection1.Open();
try {
// Cria objeto associado ao comando SQL
ADOCommand Cmd = new ADOCommand("select * from Products", adoConnection1);
ADODataReader Produtos;
// Executa o comando e coloca o resultado no DataReader
Cmd.Execute(out Produtos);
try {
// Pega os valore e coloca em um DataTable
DataTable Tbl = ConvDeDataReader(Produtos);
// Exibe o DataTable no grid
dataGrid1.DataSource = Tbl;
}
finally {
// Fecha o DataReader
Produtos.Close();
}
}
finally {
// Fecha a conexão
adoConnection1.Close();
}
}

Você deve acrescentar também a linha "using System.Data.ADO" no início do programa.

Observe o seguinte:

  • A consulta foi feita da mesma forma que anteriormente para exibição em páginas Web;
  • A função ConvDeDataReader pega a estrutura e os dados do DataReader e copia-os para um DataTable. Não achei um método ou propriedade dos componentes capaz de fazer isso diretamente; talvez esta capacidade venha a aparecer na versão final.

Conclusão

O componente DataTable é bastante importante na arquitetura de bancos de dados ADO.NET. Usar este tipo de componente tanto para pegar um resultado de uma consulta como para exibir o resultado em um DataGrid é bastante fácil.

Mauro Sant'Anna

Mauro Sant'Anna - Mauro tem mais de 20 anos de experiência no desenvolvimento de software, com produtos publicados no Brasil, Portugal e Estados Unidos, além de extensa experiência em treinamento e consultoria no desenvolvimento de software, tanto criando material como ministrando cursos.
Mauro é um "Microsoft Most Valuable Professional" (MVP - www.microsoft.com/mvp), “Microsoft Regional Director” (RD - www.microsoft.com/rd), membro do INETA Speaker’s Bureau (www.ineta.org) e possui as certificações MCP, MCSA (Windows 2000/2003), MCAD (C# e VB), MCDBA, MCSE (Windows 2000/2003).
Sua empresa, a M. A. S Informática (www.mas.com.br), treinou centenas de turmas em desenvolvimento de software nos últimos anos.