08/05/12
ADO.NET - Boas Práticas de Programação
ADO.NET - Roteiro básico e Boas Práticas
Confuso com tantos conceitos novos, com tantas siglas e acrósticos ? Qual provedor usar ? Devo usar DataSet ou
DataReader ?
Se essas e outras dúvidas te atormentam, você chegou ao artigo certo. Espero que após terminar a leitura pelo menos
metade das suas dúvidas estejam resolvidas ou encaminhadas. Esse é objetivo deste artigo. Antes vou lançar os
fundamentos da ADO.NET para quem esta chegando agora.
Afinal o que é ADO.NET e o que ela tem a ver com o Visual Basic ?
ADO.NET
é um conjunto de assemblies que fazem parte da .NET Framework e que permitem a comunicação com os
bancos de dados realizando operações de leitura e atualização.
Para realizar esta tarefa a ADO.NET tem vários 'Clientes' de fonte de dados os quais se encontram no espaço de nomes namespace - System.Data. Assim temos:
System.Data.SqlClient - permite o acesso ao banco de dados SQL Server 7.0 ou superior;
System.Data.OleDb - permite o acesso a qualquer outra fonte de dados exceto(não recomendado) para o SQL
Server 7.0 ou superior;
System.Data.Oracle - permite o acesso ao banco de dados Oracle.
Quais são os componentes básicos da ADO.NET ?
Como já disse anteriormente a ADO.NET possui diversos clientes logo teremos um componente para cada cliente. Assim
temos:
Nota: Para simplificar listei somente os componentes do SqlClient e OleDb
Note
que temos um componente SqlConnection e OleDbConnection em ambos os clientes para a conexão, um componente
SqlCommand e OleDbCommand para o objeto Command e assim por diante.
Qual o componente mais importante do ADO.NET ?
Na verdade todos os componentes são importantes pois estão inter-relacionados e funcionam em harmonia para atingir
um objetivo.
Dentre eles o componente que deve ser usado em primeiro lugar é o objeto XXXConnection pois a primeira coisa que
devemos fazer antes de qualquer outra atividade é efetuar a conexão com a fonte de dados.
O que significa criar uma conexão com uma fonte de dados ?
Criar
uma conexão com uma fonte de dados significa usar o componente apropriado e fornecer informações ao
componente para que ele possa encontrar a base de dados e poder acessar informações a partir dela.
Como exemplo, vamos supor que você deseja criar uma conexão com um banco de dados SQL Server que esta instalado
na sua máquina local e acessar o banco de dados Northwind. Neste caso você deve informar o seguinte:
Usar o provedor de dados SQL Server .NET Data Provider do namespace System.Data.SqlClient
O nome do servidor onde esta a base de dados
O nome da base de dados
O nome do usuário e a senha
Nota: O namespace System.Data.SqlClient deverá ser declarado via imports no início do código.
www.macoratti.net/adn_bpu1.htm
1/5
08/05/12
ADO.NET - Boas Práticas de Programação
Como exemplo de conexão deste acesso temos o seguinte código:
Dim conexao as String
strconexao = "data source=localhost;" & _
"initial catalog=Northwind" & _
"integrated security=SSPI;"
Dim conexao as SqlConnection = New SqlConnection(strconexao)
O que são adaptadores e como funcionam ?
Os
adaptadores(objeto DataAdapter) estão encarregados de chamar os comandos de leitura, atualização, inclusão e
exclusão de informações em uma fonte de dados.
Com base nesta informação chegamos a conclusão que cada Adaptar deverá ter:
Uma conexão para saber de onde irá acessar os dados
Um comando Select : para saber quais dados acessar
Um comando Insert : para saber quais dados incluir
Um comando Update : para saber quais dados por atualizar
Um comando Delete : para saber quais dados pode excluir
O código exemplo que cria um Adaptador para o SQL Server usando a conexão acima criado é o seguinte :
Dim da As SqlDataAdapter = New SqlDataAdapter("Select * from Clientes, conexao)
A linha de código acima cria uma instância do Adaptador e atribui ao SelectCommand uma sentença SQL que lê todos os
registros da tabela Clientes. (O resultado obtido com o SelectCommand pode ser usado para preencher um DataReader ou
um DataSet.)
Os comandos possuem a função que pode ser chamada para que um comando seja executado; podemos ainda informar
que dados desejamos receber.
Assim, se desejamos executar um procedimento armazenado sem receber nenhum valor usamos: ExecuteNonQuery. Se
desejamos receber um valor usamos: ExecuteScalar.
Abaixo o código exemplo que retorna um valor para a variável valor:
Dim valor as String = da InserCommand.ExecuteScalar
Abaixo o código exemplo que não retorna valor algum:
da DeleteCommand.ExecuteNonQuery
O que são os objetos Commands e como funcionam ?
Podemos
ter basicamente 4 comandos : Select, Update, Insert e Delete.
Cada comando possui uma sentença SQL que dirá ao Adaptador(DataAdapter) como realizar a respectiva tarefa.
Para realizar tarefas simples usando sentenças SQL podemos usar o objeto CommandBuilder que funciona como um
construtor automático dos comandos SQL básicos. Exemplo:
Dim comandoBuilder As SqlComandBuilder = New SqlCommandBuilder(da)
Com a linha de código acima criamos os comandos : Insert, Update e Delete para o Adaptador da.
Vamos juntar os trechos de códigos já escritos para obter o código completo para preencher um DataSet com todos os
www.macoratti.net/adn_bpu1.htm
2/5
08/05/12
ADO.NET - Boas Práticas de Programação
dados da tabela Clientes da base de dados Northwind do SQL Server 2000:
Dim conexao as String
strconexao = "data source=localhost;" & _
"initial catalog=Northwind" & _
"integrated security=SSPI;"
Dim conexao as SqlConnection = New SqlConnection(strconexao)
Dim da As SqlDataAdapter = New SqlDataAdapter("Select * from Clientes, conexao)
Dim comandoBuilder As SqlComandBuilder = New SqlCommandBuilder(da)
Dim ds As DataSet
da.Fill(ds,"Clientes")
Qual Provedor de dados .NET Framework eu devo usar ?
Todos queremos obter um melhor desempenho para nossas aplicações. Principalmente as aplicações com acesso a base de dados.
Para alcançar o melhor desempenho para sua aplicação com acesso a dados você deve usar o provedor de dados .NET mais
adequado para a sua fonte de dados. Como existem diversas opções de provedores de dados disponíveis na .NET Framework
oriente-se pela tabela abaixo para encontrar qual provedor de dados usar para sua fonte de dados e assim obter um melhor
desempenho:
Provedor .NET
SQL Server .NET Data
Provider
Detalhes
Localizado no namespace System.Data.SqlClient
Recomendado para aplicações em 3 camadas usando como banco de dados o SQL Server
version 7.0 ou superior.
Recomendado para aplicações em uma camada usando o Microsoft Data Engine (MSDE) ou o
Microsoft SQL Server 7.0 ou superior.
Para usar o Microsoft SQL Server versão 6.5 e anterior você deve usar o OLE DB Provider for
SQL Server com o OLE DB .NET Data Provider.
OLE DB .NET Data Provider
Localizado no namespace System.Data.OleDb.
Recomendado para aplicações em 3 camadas usando o Microsoft SQL Server 6.5 ou anterior,
ou, qualquer provedor OLE DB que suporta a interface OLE DB listada em OLE DB Interfaces
Used by the OLE DB .NET Data Provider no .NET Framework SDK.
Recomendado para aplicações em uma camada usando o banco de dados Microsoft® Access.
(A utilização do banco de dados Microsoft® Access para aplicações em 3 camadas não é
recomendado.)
Para acesso usando ODBC - Open Database Connectivity - existe um provedor de dados ODBC
.NET disponível para download aqui. (O provedor já esta incluído na versão 1.1 da .NET
Framework)
Nota: O suporte para o provedor OLE DB para ODBC (MSDASQL) não esta mais disponível.
ODBC .NET Data Provider
Localizado no namespace Microsoft.Data.Odbc. (a partir da versão 1.1 do .NET Framework).
Para a versão anterior do.NET Framework (1.0) o provedor pode ser baixado aqui: download
Fornece acesso a fonte de dados que são conectados via driver ODBC.(Deve ser usado
somente quando não houver outra alternativa de conexão com a fonte de dados.)
.NET Data Provider for
Oracle
Localizado no namespace System.Data.OracleClient (a partir da versão 1.1 do .NET Framework).
Para a versão anterior do .NET Framework (1.0) o provedor pode ser baixado aqui: download.
Fornece acesso a base de dados Oracle(versão 8.1.7 e superior).
.NET Data Provider
Personalizado
ADO.NET fornece um conjunto mínimo de interface que lhe permite implementar seu próprio
provedor de acesso a dados .NET. Para maiores informações veja o link: Implementing a .NET
Data Provider.
SQLXML Classes
gerenciadas
O Microsoft SQL Server 2000 (SQLXML 3.0) contém classes SQLXML gerenciadas que
permitem a você acessar a funcionalidade XML do Microsoft SQL Server 2000 ou superior.
Essas classes permitem executar modelos XML, , realizar consultas usando a linguagem XML
Path Language (XPath) sobre dados no servidor, ou realizar atualizações usando o
Updategrams ou Diffgrams.
www.macoratti.net/adn_bpu1.htm
3/5
08/05/12
ADO.NET - Boas Práticas de Programação
SQLXML 3.0 esta disponível para download: download.
Resumindo:
Vai Acessar uma fonte de dados
SQL Server 7.0 ou superior (2000,2005)
ou MSDE
Oracle
MS Access ou SQL Server 6.5
ODBC (DBF, Dbase, Paradox,etc...)
USE o seguinte
namespace
Use o seguinte Provedor
System.Data.SqlClient
SQL Server .NET Data Provider
System.Data.OracleClient
System.Data.OleDb
Microsoft.Data.Odbc
NET Data Provider for Oracle
OLE DB .NET Data Provider
ODBC .NET Data Provider (*)
(*) Utilize ODBC somente em último caso.
Como trabalhar com DataReaders, DataSets, DataAdapters, e DataViews ?
ADO.NET, até a versão 1.1, fornecia dois objetos para retornar e armazenar dados em memória: DataSet e DataReader.
DataReader - Fornece um acesso conectado somente-leitura e somente-para-frente a uma fonte de dados.
DataSet - Fornece um representação relacional em memória de dados , sendo um conjunto completo de dados que incluem tabelas
que contém dados, restrições de dados e relacionamentos entre as tabelas. O acesso é desconectado.
- Quando você usa um DataSet frequentemente você também usa um DataAdapter (e possivelmente um CommandBuilder)
para interagir com sua fonte de dados.
- Quando você usa um DataSet você pode empregar um DataView para aplicar ordenamento e filtragem nos dados do DataSet.
- O DataSet também pode ser herdado para criar um DataSet fortemente tipado com o objetivo de expor tabelas, linhas e colunas
como propriedades de objetos fortemente tipados.
Afinal DataSet ou DataReader ?
Para decidir se você deve usar um DataSet ou um DataReader em sua aplicação de acesso a dados, você deve considerar o nível
de funcionalidade que vai precisar usar na sua aplicação.
Você deve usar um DataSet em sua aplicação quando:
v ocê
precisar trabalhar com mais de uma tabela de dados simultaneamente.
Você precisar de navegação entre múltiplas tabelas de resultados.
você precisar manipular dados de múltiplas fontes: banco de dados , arquivos XML, arquivos textos, planilhas
eletrônicas, etc...
você precisar trocar dados entre camadas ou usar um Web Service XML.
você precisar reutilizar o mesmo conjunto de linhas para alcançar desempenho através de cache de dados (via
ordenação, busca ou filtro de dados)
você precisar efetuar uma grande quantidade de processamento por linha.
você precisar manipular dados usando operações XML como XLST ou consultas XPath.
Você deve usar um DataReader em sua aplicação quando:
Você
você
você
você
você
precisar trabalhar somente com uma tabela de dados por vez
não precisar usar cache de dados
precisar somente exibir os dados de uma tabela
precisar acessar de forma rápida e de uma vez os dados de uma forma somente-leitura e somente-para-frente
precisar processar uma quantidade de dados muito grande para caber na memória
Nota: O DataAdapter usa o DataReader par preencher o DataSet. Desta forma , o desempenho ganho pela utilização do
DataReader é que você salva na memória os dados que o DataSet irá consumir.
Em resumo: utilize um DataReader sempre que você puder, deixando a utilização de um DataSet para os casos realmente necessários.
Dicas para utilizar melhor o DataReader
O DataReader deve ser fechado antes de acessar qualquer parâmetro de saida para um Command associado.
Sempre feche o DataReader quando você terminou de ler os dados. Se a conexão que você esta usando é usada
somente para retornar o DataReader feche a conexão imediatamente depois de fechar o DataReader.
O DataReader não pode ser trocado entre camadas pois foi criado para acesso a dados conectado.
Somente um DataReader pode ser aberto de cada vez.
www.macoratti.net/adn_bpu1.htm
4/5
08/05/12
ADO.NET - Boas Práticas de Programação
Ao acessar os dados de uma coluna use os conectores tipados como GetString, GetInt32 ao invés de GetValue.
Se você estiver terminando de ler dados de um DataAdapter mas ainda tem uma grande quantidade de dados não
lidos pendentes, use o comando Cancel no Command antes de efetuar o Close no DataReader. Se você dar um close
no DataReader isto provocará o retorno dos dados pendentes antes de fechar o cursor. Ao usar o Cancel no
Command você estará descartando os dados pendentes que o DataReader ainda não leu quando ele foi fechado.
Boas práticas para acesso a dados com ADO.NET
Abra conexões o mais tarde possível e Feche as conexões o mais cedo possível;
Em operações que envolvam alterações de dados (UPDATE, INSERT, DELETE) em mais de uma tabela
simultaneamente sempre utilize Transações;
De forma geral todas as tabelas devem possuir uma chave primária
Ao montar instruções SQL dê preferência a utilização de parâmetros nas strings SQL e evite a concatenação de
strings. Desta forma evita-se erros e ataques de injeção SQL. A utilização de parâmetros permite que o SGBD
compile o código SQL apenas uma vez;
Ao utilizar o operador LIKE em instruções SQL a string usada na cláusula é o símbolo % e não o *. O correto é :
SELECT nome FROM tabela where nome like 'Mac%'
Procure construir filtros e ordenações diretamente na instrução SQL , usando as cláusulas WHERE, ORDER e GROUP
e não via código;
Procure evitar o uso do coringa (*) em instruções SQL com SELECT procurando nomear os campos que deseja obter
da base de dados e sempre usando uma condição para evitar que todos os registros sejam selecionados. Evite :
SELECT * from Tabela.
Até o próximo artigo VB.NET ...
José C arlos Macoratti
www.macoratti.net/adn_bpu1.htm
5/5