VB .NET - Curso Prático ADO .NET - Desenvolvendo uma aplicação : Conceitos ADO .NET - V


Na quinta parte do nosso curso prático vamos abordar a tecnologia ADO .NET que será usada em nosso projeto para acessar e persistir informações no banco de dados SQL Server.

A ADO .NET utiliza uma arquitetura de dados desconectada; nesta arquitetura um aplicativo se conecta à fonte de dados apenas para acessar ou atualizar dados, isso significa que depois da aplicação se conectar a fonte de dados e retornar os dados, a conexão é encerrada. Para atualizar a fonte de dados, a implementação se conecta novamente. Portanto, a aplicação se conecta à fonte de dados apenas para salvar ou recuperar os registros. Além disso, o uso da arquitetura de dados desconectada garante uma ótima utilização do sistema porque os recursos ADO.NET não mantém bloqueios de banco de dados ou conexões ativas para períodos de tempo prolongados.

Todos os recursos ADO.NET são oferecidos através dos Namespaces (espaços de nomes) da biblioteca de nomes da classe .NET. 

Os componentes ADO.NET foram desenhados para tratar o acesso aos dados e a manipulação dos mesmos. Os componentes que podemos chamar de pilares do ADO.NET são :

A ADO.NET pode acessar dados de diversas formas, as mais comuns são via: OLE DB , SQL e ODBC. Cada objeto possui uma versão para cada uma das maneiras aqui mencionadas ; assim temos o objeto OleDataAdapter para acesso genérico mais usado para Microsoft Access e SqlDataAdapter para acesso a SQL Server . Abaixo uma figura ilustrando isto:
 

Obs: Temos atualmente diversos conectores de terceiros disponíveis de forma que com ADO .NET podemos acessar diversos banco de dados como MySQL, PostgreSQL, Oracle, etc. usando provedores nativos para esses banco de dados e ganhando assim em desempenho. Veja neste link uma lista de providers: http://msdn.microsoft.com/en-us/data/dd363565.aspx

Benefícios da ADO .NET

Se vamos usar ADO .NET devemos ter motivos suficientes para justificar essa escolha. A seguir temos uma resumo dos principais benefícios da ADO .NET:

1- Escalabilidade

A arquitetura de dados desconectada permite que os aplicativos sirvam a mais usuários de forma mais eficiente em comparação com uma arquitetura de dados conectada. Isto porque na arquitetura de dados desconectada, a conexão com a fonte de dados é encerrada assim que os dados são recuperados da fonte de dados, deixando a fonte de dados disponível para outros usuários. Em outras palavras, as aplicações criadas no ADO.NET podem gerir eficazmente vários usuários. Portanto, ADO.NET faz aplicações escaláveis.

2- Desempenho

Na ADO .NET usamos XML para transferir dados entre aplicações sendo que nenhuma conversão de tipos de dados é requerido e dessa forma temos um melhor desempenho.

3- Programação

A ADO.NET permite uma programação rápida e fácil com um mínimo de erros permitindo que seja usado a programação tipada a qual torna o código mais legível. Com a programação tipada temos a verificação da existência de erros em tempo de compilação, a qual aumenta a segurança do código.

4- Interoperabilidade

Com o suporte ao XML pela ADO.NET, a transferência de dados com qualquer outro aplicativo que interpreta XML é facilitada. Portanto, as aplicações criadas no ADO.NET são interoperáveis com outros aplicativos.

5- Manutenabilidade

Usando ADO.NET, você pode criar aplicativos que são logicamente divididos em camadas. Por exemplo, você pode criar um aplicativo com camadas separadas para a interface do usuário, lógica de negócios e acesso a dados. Dividindo uma aplicação em camadas lógicas simplifica a manutenção da aplicação. Além disso, você pode adicionar camadas para uma aplicação ADO.NET como e quando necessário.

Mas porque não utilizamos uma ferramenta ORM como o Entity Framework ou NHibernate ?

Primeiro porque o escopo do nosso curso é de nível básico dirigido para quem esta iniciando com o VB .NET, além disso, quando você usa qualquer outra ferramenta ORM você esta adicionando mais uma camada ao seu código, e isso vai ter um impacto no desempenho. É claro que isso pode ser justificado dependendo do cenário, mas de forma geral usar ADO .NET trás um melhor desempenho.

Resumo dos principais conceitos da ADO .NET

A ADO.NET permite que você crie várias camadas distribuídas e aplicações de compartilhamento de dados permitindo que você acesse os dados de um banco de dados relacional, uma fonte XML ou outra aplicação. Para que você possa acessar e gerenciar dados, a ADO.NET fornece dois componentes:

O .NET Data Provider ou provedor de dados .NET é usado para acessar os dados, e o DataSet é usado para manipular os dados. A figura abaixo ilustra os componentes do ADO.NET:

O .NET data provider vincula um aplicativo a uma fonte de dados e permite a aplicação acessar os dados a partir dele. Usando o provedor de dados .NET, Você pode realizar as seguintes tarefas:

Usando ADO.NET, você pode acessar e gerenciar dados de diferentes fontes de dados. Para que você possa acessar e manipular diferentes fontes de dados, ADO.NET fornece diferente tipos de provedores de dados.

 

Para permitir que um aplicativo possa se comunicar com uma fonte de dados, o .NET Data provider utiliza quatro objetos. Esses objetos são conhecidos como os objetos do provedor de dados. NET.

  1. Objeto Connection
  2. Objeto Command
  3. Objeto DataReader
  4. Objeto DataSet

ADO.NET - Objeto Connection
 

Como você já deve ter desconfiado , o objeto Connection têm a função de gerar uma conexão com uma fonte de dados sendo portanto o objeto fundamental no acesso a dados.

 

Para estabelecer uma conexão com uma fonte de dados o objeto Connection usa a propriedade ConnectionString que é a string de conexão que deverá ser informada para que a conexão seja efetivamente aberta.

 

Após realizada a conexão com a fonte de dados podemos usar objetos para receber e enviar dados para a fonte de dados , dentre estes objetos podemos citar : Command e DataAdapter.


ADO.NET - Objeto Command


Os objetos
Command são usados para executar declarações SQL  e procedimentos armazenados (stored procedures). Os métodos usados para realizar estas tarefas são :

Para criar um comando você já deve ter uma conexão criada . Assim para um banco de dados SQL Server  devemos usar um objeto SqlCommand , já se usarmos provedores OLE DB deveremos usar o objeto OLEDCommand . Vejamos um exemplo de criação de um comando :

 

ADO.NET - Objeto DataReader


Os objetos
DataReader é uma das maneiras mais fáceis para ler os dados retornados pelos objetos Command . Eles permitem acessar e percorrer os registros no modo de somente leitura e somente para frente - forward-only . Não oferecem acesso desconectado e não permitem alterar ou atualizar a fonte de dados original sendo usado para obter rapidamente dados de apenas leitura. Apresenta poucos recursos mas seu desempenho é muito melhor do que o oferecido pelos DataSet.
 

As propriedades e métodos mais usadas dos objetos DataReader são :

  1. FieldCount - informa o número de colunas da linha de dados atual
  2. IsClosed - Indica se o objeto DataReader esta fechado.
  3. RecordsAffected - especifica o número de linhas alteradas , excluídas ou incluídas na execução de uma declaração SQL
  4. Item (n) - obtêm o valor da enésima coluna no seu formato nativo.
  5. Close - Método que fecha o objeto
  6. GetName - Método que retorna o nome da enésima coluna.
  7. Read - método que permite ao DataReader avançar para o próximo registro
  8. IsDbNull - método que informa se a enésima coluna possui um valor nulo.

Para criar um objeto DataReader usamos o método ExecuteReader de um objeto Command . Abaixo um exemplo simples de como fazer isto :

Dim leitor As SQLDataReader = cmd.ExecuteReader()

 

ADO.NET - Objeto DataAdapter

 

A ADO.NET usa a arquitetura de dados desconectado e essa arquitetura é implementada em um aplicativo usando datasets. Um dataset é um banco de dados virtual que armazena os dados recuperados a partir de qualquer fonte de dados. A ADO.NET fornece objeto DataAdapter para ajudá-lo a manipular datasets.

O objeto DataAdapter age como um elo entre o conjunto de dados e a fonte de dados. ele permite a transferência de dados do dataset para a fonte de dados e vice-versa e permite que você possa acessar e manipular os dados, o objeto DataAdapter fornece múltiplas propriedades.

Sua função basicamente é a seguinte :

  1. acessar a fonte de dados através de uma conexão prévia
  2. fazer a consulta na base de dados
  3. Obter os dados
  4. Preencher o DataSet

Não pense que o serviço do DataAdapter pare por ai ; quando os dados que foram alterados no DataSet precisam voltar para o banco de dados para atualizar a fonte de dados , novamente o DataAdapter atua :

  1. Ele lê os dados do DataSet
  2. Verifica quais dados foram alterados
  3. Envia ao banco de dados via conexão os dados para atualizar a fonte de dados.

Para acessar o banco de dados , executar o comando SQL via DataAdapter , trazer os dados e preencher o DataSet usamos o método Fill .

O método Fill retorna a linhas de uma fonte de dados usando a declaração SELECT definida por uma propriedade SelectCommand associada. O objeto Connection associado com a declaração SELECT precisa ser válido mas não precisa ser aberto. Se a conexão for fechada antes de você chamar o método Fill ela será aberta para que os dados possam ser retornados e em seguida fechada novamente. Se a conexão estiver aberta ela permanecerá aberta após o uso do método Fill.

O método Fill então irá incluir as linhas ao objeto DataTable de destino , criando o objeto DataTable , se ele ainda não tiver sido criado. Ao criar o objeto DataTable a operação Fill normalmente cria somente colunas com metadata.

Se o DataAdapter encontrar colunas duplicatas enquanto preenche o DataTable ele irá gerar nomes para as colunas seguintes usando o padrão "columnname1","columnname2", "columnname3" e assim por diante .  Quando múltiplos conjuntos de registros forem incluídos em um DataSet cada conjunto de registro será colocado em uma tabela separada.

Tabela a seguir lista as propriedades comumente usados do objeto DataAdapter:

Propriedade Descrição
SelectCommand Seleciona registros da fonte de dados
InsertCommand Inclui registros em uma fonte de dados
UpdateCommand Atualiza os registros de uma fonte de dados
DeleteCommand Deleta registros de uma fonte de daos

 

ADO.NET - Objeto DataTable

 

Como já dissemos um objeto DataTable representa uma ou mais tabelas de dados em memória. Os objetos DataTable estão contidos no objeto DataSet e/ou DataView.  Abaixo temos uma relação das principais propriedades do objeto DataTable:

Vamos criar um objeto DataTable via código com os seguintes campos : Código , Nome e Endereço ; para isto temos que seguir os seguintes passos :

ADO.NET - Objeto DataView

Usamos o DataView para mostrar uma visão dos dados contidos em um DataTable , com isto você pode ter vários DataViews ligados a um mesmo DataTable , sendo que cada um exibe um visão diferente dos dados. O objeto DataTable possui um DataView padrão que é acessado através da propriedade DefaultView.

As principais propriedades do objeto DataView são :

Vimos então que um DataView permite a você criar diferentes visões dos dados armazenados em um objeto DataTable . Geralmente usamos estas características em aplicações com controles vinculados (DataBinding). Um DataView oferece uma visão dinâmica dos dados cujo conteúdo , ordem e membership  refletem as mudanças ocorridas no objeto DataTable relacionado a medida que ocorrem.

 

Isto é não é o mesmo que usar o método Select do objeto DataTable que retorna um vetor DataRow da tabela para um filtro ou ordenação particular que refletem as mudanças na tabela relacionada mas cuja ordenação e o membership permanecem estáticos. Tudo isto faz com que o DataView seja ideal para ser usado em aplicações com DataBindind.

Apesar disto o DataView não pode ser tratado como uma tabela nem pode fornecer uma visão de junções de tabelas , e você não pode excluir colunas que existem na tabela fonte , nem pode anexar colunas a tabela fonte.

ADO.NET - Objeto DataSet

Vamos falar agora sobre DataSet. Se você já se aventurou a criar algum programa para banco de dados usando o Visual Basic já ouviu pelo menos falar no objeto Recordset . Afinal era ele que permitia o acesso , exibição e a manipulação dos dados . O objeto DataSet veio para substituir com vantagens o objeto recordset e guarda poucas similaridades com o objeto recordset. Enquanto o objeto recordset representa uma coleção de tabelas de dados O objeto DataSet representa uma cópia do banco de dados em memória.

 

A classe DataSet é membro do namespace System.Data e representa o primeiro dos dois maiores componentes da arquitetura ADO.NET  o outro membro seriam os provedores Data .NET. Podemos resumir os atributos como segue:

O objeto DataSet fornece as principais funcionalidades para criar aplicações para banco de dados desconectados , embora suporte também o modelo conectado através de leitores de dados (DataReader).

 

A classe DataSet é derivada da classe System.ComponentModel.MarshalByValueComponent da qual ela recebe a habilidade de ser serializada , incluída na caixa de ferramentas do VS.NET e visualmente desenhada em um descritor. Os principais métodos  e eventos da classe DataSet são :

 

Membro Descrição
Propriedades
CaseSensitive obtêm ou define se a comparação entre strings será sensível a caixa alta/caixa baixa
DataSetName Define ou obtêm o nome do DataSet
DefaultViewManager Obtém uma visão padrão dos dados permitindo busca , ordenação e filtragem
EnforceConstraints Especifica se uma regra de relação definida será seguida apos a ocorrência de uma atualização
ExtendedProperties Uma coleção de informação customizadas que reside no DataSet
HasErrors Indica se há erros em qualquer linha de qualquer tabela
Namespace Obtêm ou define um namespace XML para o DataSet
Prefix Define ou obtêm um conjunto de prefixos XNL para o namespace
Coleções
Relations Uma coleção de relações hospedadas em um objeto DataRelationCollection que liga tabelas através de chaves estrangeira
Tables Uma coleção de tabelas que armazena os dados atuais
Métodos
AcceptChanges Grava todas as alterações para o DataSet
Clear Remove todas as linhas de todas as tabelas
Clone Faz uma cópia da estrutura mas não os dados de um DataSet
Copy Faz uma cópia a estrutura e os dados de um DataSet
GetChanges Retorna uma cópia do DataSet com apenas as colunas alteradas ou aquelas que coincidem com o filtro definido em DataRowState
GetXml Retorna uma representação exm XML dos dados
GetXmlSchema Retorna uma representação XML da estrutura de um DataSet
HasChanges Retorna um valor indicando que existe mudanças pendentes
InferXmlSchema Infere a estrutura de um DataSet baseada em um arquivo ou fluxo
Merge Mescla o DataSet com o provedor
ReadXml Carrega um esquema XML e dados para um DataSet
ReadXmlSchema Carrega um esquem XML para um DataSet
  Descarta as alterações feitas em um DataSet
Reset Reverte o DataSet ao seu estado original
WriteXML Escreve os dados e o esquema XML para um arquivo ou fluxo de dados
WriteXmlSchema Escreve o esquema XML para um arquivo ou fluxo
Eventos
MergeFailed Evento disparado quando uma mesclagem falha devido a uma violação de regras de validação.

Como estamos usando ADO .NET em nosso projeto ?

Em nossa aplicação iremos usar o provedor SQL Server .NET Data Provider este provedor permite acessar dados de qualquer banco de dados SQL Server 7.0 ou superior e utiliza o protocolo Tabular Data System (TDS) para se conectar ao bancos de dados Microsoft SQL Server. Usando o protocolo TDS, o provedor pode se conectar diretamente a um SQL Server. (Para acessar dados de versões anteriores do SQL Server voce deve usar o provedor OLE DB .NET Data Provider.)

As classes associadas ao SQL Server .Net Provider são armazenados no Namespace System.Data.SqlClient. Portanto, para implementar o provedor dados em seu aplicativo, você precisa importar esse namespace. Você pode usar a seguinte instrução para importar este namespace: Imports System.Data.SqlClient

O namespace System.Data.SqlClient inclui outros namespaces e classes relacionadas com o provedor SQL Server abaixo vemos uma tabela que descreve algumas das classes desse namespace:

Classe Descrição
SqlConnection Representa uma conexão com o banco de dados
SqlCommand Representa uma instrução Transact-SQL ou stored procedure que pode ser executada no banco de dados
SqlDataReader Representa um objeto somente-leitura para frente usado para ler um fluxo de dados a partir do banco de dados
SqlDataAdapter Representa os comandos e a conexão usada pela aplicação para transferir dados a partir do banco de dados e vice-versa.
SqlException Representa uma exceção lançada quando o banco de dados retornar um erro ou alerta
SqlError Usado para criar objetos que podem armazenar erros ou alertas retornados pelo banco de dados

Na próxima parte do tutorial veremos como tratar erros e exceções.

Referências:


José Carlos Macoratti