De que se trata o artigo

O artigo descreve o conjunto formado pelo ADO.NET do Framework .NET. Este é composto de namespaces, classes e formas de trabalho que possibilitam um acesso mais simplificado a dados armazenados em diversos tipos de gerenciadores de banco de dados. Além de uma descrição dos principais recursos, são consideradas também as melhores práticas a serem adotadas ao usar estas tecnologias, pensando principalmente em desempenho e em diminuição dos problemas que poderão ocorrer.

Para que serve

ADO.NET serve para escrever aplicações conectadas ao banco de dados. Conhecendo as melhores formas de usar os seus recursos e ainda, qual recurso usar em qual caso, o desenvolvedor terá resultados melhores no seu trabalho e poderá com o tempo, fazer ajustes para suas aplicações terem um melhor desempenho.

Em que situação o tema é útil

É útil no desenvolvimento de projetos que usam a tecnologia ADO.NET. Além disto, se estiver enfrentando gargalos de desempenho, poderá verificar se algum ponto foi deixado de lado e se existe alguma medida que pode ser tomada para sua melhoria.

Boas Práticas com ADO.NET

As tecnologias devem facilitar o trabalho em qualquer área. Ao desenvolver aplicações voltadas para o trabalho com bancos de dados, muitos problemas precisam ser resolvidos com ADO.NET. Entretanto, como qualquer ferramenta, se não houver um conhecimento maior do seu funcionamento, alguns enganos podem comprometer o resultado final. Ao demonstrar a infraestrutura básica desta tecnologia, qual componente usar em cada caso e algumas boas práticas a serem adotadas, será possível fortalecer alguns conceitos que ajudarão ao desenvolver projetos para o mundo real. Um projeto de exemplo foi criado com o propósito de usar algumas das ideias expostas. Este projeto está colocado mais à frente no artigo.

O ADO.NET é um conjunto de namespaces, classes e interfaces, usado para providenciar um acesso consistente aos diversos tipos de fonte de dados. Outro objetivo de ADO.NET é diminuir significativamente a quantidade de código necessário para interagir com as fontes de dados. Com seus componentes, muitas tarefas podem ser configuradas visualmente, principalmente se o desenvolvedor estiver usando as versões mais recentes do Visual Studio. Uma das principais tarefas do ADO.NET é separar as tarefas de acesso aos dados das de manipulação em partes que podem trabalhar independentes ou em conjunto

Modelos de acesso conectado e desconectado

Existem várias questões a serem consideradas quando se trabalha com ADO.NET. A primeira sem dúvida é o modelo de acesso aos dados que pode ser feito de duas formas: conectado e desconectado. Ao trabalhar conectado o desenvolvedor precisa estabelecer um canal com a fonte de dados por onde será feita a leitura ou escrita com os dados. Isto só pode ser feito enquanto o canal estiver aberto.

Operações tipicamente conectadas são:

1. Execução de inserção, alteração e exclusão dos dados no banco;

2. Leitura unidirecional dos dados. Este tipo de leitura não permite uma navegação bidirecional pelos registros. Um uso típico é a leitura dos dados para geração de relatórios ou exibição em páginas estáticas.

As classes que são indicadas para este trabalho são implementações das Interfaces IDbCommand, IDbDataReader e IDbConnection. Mais à frente será considerada a questão dos DataProviders, que fazem implementações customizadas destas classes.

O modelo de acesso permite que se carreguem os dados para serem usados pela aplicação sem ser necessário manter uma conexão permanente com a fonte de dados. Assim, podem-se editar os dados, navegar pelos registros sendo que só quando for necessário, seja estabelecida uma conexão com o banco de dados para o eventual envio das alterações feitas localmente. O trabalho é feito basicamente com as classes DataTable e DataSet e com as implementações das interfaces de IDataAdapter e IDataParameter.

Estas interfaces definem o modelo de acesso que o Framework .NET provê. Cada banco de dados deve implementar as classes mais apropriadas para o acesso sendo que os padrões do ADO.NET são: System.Data.OleDb, Sytem.Data.Odbc, System.Data.SqlClient e System.Data.OracleClient (que deve ser baixado).

Data Providers

Os Data Providers proporcionam uma camada mínima entre as fontes de dados e o código por serem leves e causarem pouco impacto. Estes componentes servem de pontes entre a fonte de dados e a aplicação. Uma preocupação inicial é usar o data provider correto para o tipo de banco de dados que se está usando. Observe na Figura 1 onde é feito um comparativo do acesso ao SQL Server usando o data provider nativo e outros. Note que usando o SqlClient, o número de camadas até o banco é mínimo. Os principais data providers do framework são os da Tabela 1.

Figura 1. Acesso ao SQL Server com vários data providers (fonte: MSDN)

Provider

Namespace

Considerações

SQL Server .NET Data Provider

System.Data.SqlClient

Deve ser usado para acessar o banco SQL Server. Suporta as versões mais recentes do banco.

OLE DB .NET Data Provider

System.Data.OleDb

Pode ser usado para acessar o SQL Server. É o provider padrão para o banco Microsoft Access.

ODBC .NET Data Provider

System.Data.Odbc

Usado para conectividade com bancos de dados que possuem uma arquitetura aberta de acesso. Entre os bancos que podem ser acessados estão:

• Tabelas do dBase/Clipper;

• Firebird/Interbase;

• Paradox.

.NET Data Provider for Oracle

System.Data.OracleClient

Para acessar bancos Oracle a partir da versão 8.1.7.

Custom .NET Data Provider


A arquitetura dos providers é aberta, logo, diversos fabricantes de bancos de dados podem desenvolver os seus próprios data providers como é o caso do banco Firebird (FirebirdSql.Data.Firebird).

Tabela 1. Data providers do Framework .NET

DataSet e TableAdapter

Os DataSets são os componentes usados para armazenar os dados. Representam os dados do banco de dados armazenados na memória e estruturados em tabelas. Podem ser definidos como um conjunto de objetos DataTable, também usados em conjunto com TableAdapters – estes últimos, derivados dos DataAdapters. Com estes componentes no projeto o desenvolvedor define as consultas ao banco de dados para recuperar os dados em DataTables, definindo as consultas com TableAdapters vinculados com estas. É indicado para o trabalho desconectado. Ao definir os TableAdapters vinculados com o DataTable, cria-se uma classe fortemente tipada com as colunas do banco de dados mapeadas para o projeto e com a possibilidade de definir várias consultas, sendo que cada uma gera um método Fill para preenchimento dos dados.

A classe DataSet é definida no namespace System.Data. Pode ser definida via código ou visualmente quando se usa o Visual Studio. Um dos pontos principais a se observar é que ao usar o designer, muito código é gerado para implementar as funcionalidades básicas, como a geração automática das instruções SQL para inserção, atualização e exclusão dos dados. Se muitas tabelas forem definidas sem critério e o DataSet ficar muito extenso, a sua manipulação no projeto do Visual Studio se torna muito lenta. Já citei exemplos em artigos anteriores onde a geração de uma tabela num DataSet gerou um código de mais de três mil linhas. Por isto, é importante tomar cuidado. Se for usar o DataSet, procure separar por partes do sistema. Você pode criar um DataSet para cada módulo como, por exemplo: Estoque, Finanças etc.

Usando DataAdapter

Um DataAdapter implementa a interface IDbDataAdapter e consiste entre outros componentes de um objeto para conexão com o banco e pelo menos uma instância de uma classe que implementa IDbCommand para a configuração das instruções SQL.

Como foi explicado anteriormente, as classes para o acesso aos diversos tipos de banco de dados dependem muito do data provider utilizado. Por este motivo, estou citando as interfaces para poder deixar entendido que a funcionalidade discutida está presente em todos os data providers.

Quando usar DataAdapter não é necessário configurar um objeto conection. Ao usar a string de conexão diretamente na instância do objeto, ao executar o método Fill a conexão é fechada automaticamente. Assim uma maneira típica de criar uma instância deste objeto, considerando, por exemplo, a classe SqlDataAdapter, seria desta forma:

...
Quer ler esse conteúdo completo? Tenha acesso completo