You are on page 1of 8

C# - Acessando e obtendo dados com DataReader

Este artigo mostra como acessar um banco de dados e exibir as informaes das tabelas usando ADO .NET, mais especificamente a classe DataReader. A classe DataReader fornece funes similares aos cursores SQL, os quais no so atualmente suportados na plataforma .NET. Dessa forma ela usada para retornar um fluxo de dados e somente-para-frente e somente-leitura de uma fonte de dados de forma muito eficiente. Os DataReaders so apropriados quando voc precisa simplesmente exibir o resultado de uma consulta em cenrios onde as informaes no precisam ser atualizadas nem persistidas atravs de mltiplas requisies. A classe DataReader um componente ADO .NET que possui diversos componentes para acesso e manipulao de dados e que possui dois componentes principais:

DataSet - o principal componente da arquitetura desconectada ADO .NET usado para acesso independente da fonte de dados; .NET Data Provider - inclui os objetos Connection, Command, DataReader e DataAdapter;

A seguir temos uma figura mostrando os componentes da arquitetura ADO .NET:

Neste exemplo eu vou acessar o banco de dados Northwind.mdf do banco de dados SQL Server e exibir informaes em um projeto Windows Forms usando a linguagem C#. Este um artigo para iniciantes e aborda o acesso a dados, a utilizao da classe DataReader em um projeto Windows Forms. Para criar o projeto deste artigo eu vou usar o Visual C# 2010 Express Edition (ele gratuito). Abra o Visual C# 2010 Express e crie um novo projeto do tipo Windows Forms Application com o nome acesso_DataReader; No exemplo deste artigo vamos criar uma interface que permite que usurios efetuem consultas na tabela Products do banco de dados Northwind usando uma consulta com parmetros e a classe DataReader. Vamos definir a interface com o usurio no formulrio form1.vb conforme o leiaute da figura abaixo:

Os componentes usados a partir da ToolBox foram:


1 TextBox - txtProduto; 1 Button - btnLocalizar; 1 listBox - lbProdutos

O projeto vai funcionar assim: 1. O usurio informa na caixa de texto o nome completo ou parcial de um produto que deseja localizar e clica no boto para localizar; 2. O cdigo executa uma consulta SQL usando parmetros e obtm um DataReader com as informaes exibindo-as no ListBox;

A seguir temos a imagem mostrando a tela principal do programa exibindo informaes dos produtos da tabela Products do banco de dados Northwind.mdf;

Observe que basta o usurio digitar um caractere para que produtos iniciados pelo caractere sejam exibidos e que tambm exibidos o total de produtos localizados para a consulta. Vejamos como podemos implementar o cdigo para realizar tal tarefa. Iniciamos definindo os namespaces usados no projeto:

using using using using using using

System; System.ComponentModel; System.Data; System.Windows.Forms; System.Data.SqlClient; System.Configuration;

Os namespaces System.Data e System.Data.SqlClient nos do acesso as classes de acesso a dados usadas no projeto : SqlConnection, SqlCommand, SqlDataReader e a propriedade ConnectionState; O namespace Configuration permite usarmos a classe ConfigurationManager para obter a string de conexo do arquivo App.Config que exibido abaixo:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections>

</configSections> <connectionStrings> <add name="acesso_DataReader.Properties.Settings.NORTHWNDConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\NORTHWND.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>

Alm de definir o namespace devemos incluir uma referncia no projeto a System.Configuration para isso clique com o boto direito do mouse sobre o nome do projeto e selecione Add Reference; Em seguida selecione na aba .NET a opo System.Configuration e clique Ok;

Agora vamos definir as variveis objeto usadas no projeto declarando-as logo aps no incio do formulrio form1:: SqlDataReader rdr = null; SqlConnection con = null; SqlCommand cmd = null; Crie a rotina getConexaoBD no formulrio form1 que vai obter a string de conexo do arquivo App.Config usando a classe ConfigurationManager, criar uma nova conexo e retorna a conexo criada:

private SqlConnection getConexaoBD() { //obtem a string de conexo do App.Config e retorna uma nova conexao string strConexao = ConfigurationManager.ConnectionStrings["acesso_DataReader.Properties.Settings.NORTHWNDCo nnectionString"].ConnectionString; return new SqlConnection(strConexao); }

No evento Click do boto para localizar produtos , ao lado da caixa de texto, defina o seguinte cdigo:
private void btnLocalizar_Click(object sender, EventArgs e) { try { con = getConexaoBD(); con.Open(); // define o command com a consulta dada e associa a conexo string sql = "SELECT ProductID, ProductName, UnitPrice" + " FROM Products" + " WHERE (ProductName LIKE @nomeProduto)" + " ORDER BY ProductID"; cmd = new SqlCommand(sql); cmd.Connection = con; // define o parmetro cmd.Parameters.Add(new SqlParameter( "@nomeProduto", // o nome do produto System.Data.SqlDbType.NVarChar, // o tipo do parametro 20, // o tamanho do parametro "ProductName")); // o nome da coluna // Preenche o parametro com o valor obtido do campo texto cmd.Parameters["@nomeProduto"].Value = txtProduto.Text + "%"; // Executa a cosulta rdr = cmd.ExecuteReader(); // limpa o listbox lbProdutos.Items.Clear(); //define o total de registros como zero int nuReg = 0; //percorre o leitor e exibe os valores no listbox while (rdr.Read()) { lbProdutos.Items.Add(rdr["ProductID"].ToString() + " - " + rdr["ProductName"].ToString() + " - " + rdr["UnitPrice"].ToString()); nuReg++; } //exibe o total de registros obtidos lbltotal.Text = nuReg.ToString() + " Produtos"; } catch (Exception ex) { // mensagem de erro

MessageBox.Show(ex.Message); } finally { // fecha os objetos datareader e connection if (rdr != null) rdr.Close(); if (con.State == ConnectionState.Open) con.Close(); } }

Vamos entender o cdigo usado: 1- Obtemos uma nova conexo usando a funo getConexaoBD() e a abrimos: con = getConexaoBD(); con.Open(); 2- Definimos uma instruo SQL para retornar o cdigo, nome e preo do produto onde o nome do produto dever ser igual ao nome informado pelo usurio. Aqui criarmos uma consulta parametrizada onde o parmetro foi definido como @nomeProduto. Note o sinal @ no incio do nome. A clusula LIKE permite efetuar uma consulta irrestrita:

Usando a clusula LIKE As vezes os dados que voc est desejando filtrar no tm uma ocorrncia exata, ou voc pretende realizar uma busca mais irres usar a clusula LIKE. Supondo que desejamos filtrar todos os alunos que tenham o nome comeado pelas letrar Jos, Atravs da inserir as letras desejadas e a SQL far uma busca parcial pela string informada: Algo como:

SELECT nome FROM tblalunos WHERE nome LIKE "Jos%"


Isto retornar os possveis nomes: Jos , Josu, Josimar, Josias, etc... Note que usamos o sinal de porcentagem (%) que funciona como um coringa , substituindo os demais caracteres. A seguir listamos abaixo as principais ocorrncias : Tipo de ocorrncia Padro utilizado na Consulta SQL O retorno da Pesquisa Mltiplos caracteres bb, bBb, bccccB b%b Caractere especial Mltiplos caracteres

b[%]b ab%

b%b abcdefg, abc

// define o command com a consulta dada e associa a conexo string sql = "SELECT ProductID, ProductName, UnitPrice" + " FROM Products" +

" WHERE (ProductName LIKE @nomeProduto)" + " ORDER BY ProductID"; cmd = new SqlCommand(sql); cmd.Connection = con; Definimos um objeto Command para a instruo sql definida e especificamos a conexo onde o comando ser usado. 3- Definimos o parmetro a ser usado , seu nome, tipo de dados, tamanho e nome da coluna sobre o qual ir atual e inclumos na coleo Parameters: // define o parmetro cmd.Parameters.Add(new SqlParameter( "@nomeProduto", // o nome do produto System.Data.SqlDbType.NVarChar, // o tipo de dados do parametro 20, // o tamanho do parametro "ProductName")); // o nome da coluna // Preenche o parametro com o valor obtido do campo texto cmd.Parameters["@nomeProduto"].Value = txtProduto.Text + "%" Ao definir o valor do parmetro obtemos o valor informado na caixa de texto txtProduto e acrescentamos o curinga '%' a final do texto digitado para ser usado com a clusula LIKE que j explicamos acima. 4- Executamos a consulta obtendo um DataReader (rdr), e preenchemos o controle ListBox com as informaes obtidas: // Executa a cosulta rdr = cmd.ExecuteReader(); // limpa o listbox lbProdutos.Items.Clear(); //define o total de registros como zero int nuReg = 0; //percorre o leitor e exibe os valores no listbox while (rdr.Read()) {

lbProdutos.Items.Add(rdr["ProductID"].ToString() + " - " + rdr["ProductName"].ToString() + " - " + rdr["UnitPrice"].ToString()); nuReg++; } //exibe o total de registros obtidos lbltotal.Text = nuReg.ToString() + " Produtos"; Para obter o total de registros tivemos que usar um artifcio. Quando voc usa a classe SqlDataReader ou OleDbDataReader , nao existe nenhuma propriedade RecordCount para indicar quantos registros esto sendo obtidos O objeto DataReader ou a fonte de dados geralmente sabe quantos registros esto sendo obtidos at que o ltimo registro seja enviado para o cliente. Para contornar este problema, use um dos seguintes mtodos:

Conte os registros enquanto voc percorrer o leitor. Execute uma consulta SELECT COUNT(*) primeiro. Observe que essa consulta pode ser desatualizada quando que terminar de ler os dados.

Dessa forma cumprimos nosso objetivo e obtemos os registros desejados usando um DataReader. Para melhorar o cdigo sugiro que voc crie uma camada e remova o cdigo de acesso a dados do formulrio usando as boas prticas. Pegue o projeto completo aqui: Eu sei apenas C#, mas eu gosto... C# , Simples, simples assim... Referncias:

acesso_DataReader.zip

C# - ADO .NET para iniciantes - DataReader C# - Preenchendo um DataGridView SQL - Selecionando dados com SQL Seo C# do site