C#
- Usando código independente do banco de dados
Como fazer se você precisar escrever o seu código de acesso a dados de forma que ele possa ser configurado para trabalhar com qualquer banco de dados relacional suportado por um provedor ADO .NET ?
A primeira coisa a fazer é saber se realmente você precisa desse recurso caso contrário você vai trabalhar em vão. Portanto pense bem antes de iniciar a tarefa visto que não é todo o dia que uma empresa decide trocar o seu banco de dados. Em geral a troca de um banco de dados afeta a empresa como um todo e por isso somente em casos muito extremos elas tomam a decisão de fazer a troca do fornecedor do banco de dados.
Mas vamos supor que você quer por que quer ter o seu código de maneira que ele funcione com os principais RDBMS suportados pelos provedores ADO .NET. Estou falando do SQL Server, MySQL, Oracle, MSAccess, etc...
Se você não tem a mínima ideia de como fazer esta tarefa este artigo vai lhe mostrar o caminho feliz...
O caminho feliz é programar usando as interfaces dos provedores de dados ADO .NET ao invés de usar suas classes concretas e dessa forma não depender dos recursos e dos tipos de dados que são específicos para cada implementação. Utilize também as fábricas de classes e métodos para instanciar os objetos dos provedores de dados que você pretende utilizar.
Entendeu ???
Uma das regras de ouro da orientação a objetos é: "Programe para uma interface e não para uma implementação."
E se você não entendeu até hoje o que isso significa quem sabe hoje usando o enfoque deste artigo tudo isso fique mais claro para você.
Quando você usa uma implementação específica para um provedor de dados , como por exemplo o provedor de dados SQL Server, isso pode simplificar o seu código e pode ser adequado se você precisar dar suporte a apenas a um único tipo de banco de dados ou acessar os recursos específicos fornecidos por este provedor.
Este caminho no entanto fará com que você tenha que reescrever e testar o seu código novamente se você quiser usar um provedor de dados diferente em consequência de uma troca do banco de dados que estava usando inicialmente. Você terá que reescrever toda a sua camada de acesso aos dados, isso se você adotou uma arquitetura em camada separando as responsabilidades. Se você não fez isso o trabalho será muito maior.
E quais são essas interfaces que você precisa conhecer ?
Abaixo temos resumo das principais interfaces que você deve programar quando for escrever o seu código genérico para trabalhar com qualquer provedor de dados ADO .NET:
Interface | Descrição |
IDbConnection | Representa uma conexão com
um banco de dados relacional. Você deve programar a lógica
para criar um objeto de conexão do tipo apropriado com base nas informações de configuração de seu aplicativo , ou usar o método factory DbProviderFactory.CreateConnection |
IDbCommand | Representa um comando SQL
que é emitido para um banco de dadaos relacional . Você
pode criar objetos IDbCommand do tipo apropriado usando o IDbConnection.CreateCommand ou o método factory DbProviderFactory.CreateCommand |
IDataParameter | Representa um parâmetro para um objeto IDbCommand. Você pode criar objetos IDataParameter do tipo correto usando o IDbCommand.Parameters.Add IDbCommand.CreateParameter, ou o método factory DbProviderFactory.CreateParameter. |
IDataReader | Representa o conjunto de resultados de uma consulta de banco de dados e fornece acesso para as linhas e colunas. Um objeto do tipo correto será devolvido quando você chamar o o método IDbCommand.ExecuteReader. |
IDbDataAdapter | Representa o conjunto de
comandos utilizados para preencher uma
System.Data.DataSet a partir de um banco de dados
relacional e atualizar o banco de dados com base nas alterações do DataSet. Você deve programar a lógica para criar um objeto adaptador de dados do tipo apropriado com base em informações de configuração de seu aplicativo ou usar o método DbProviderFactory.CreateAdapter |
A classe System.Data.Common.DbProviderFactory fornece um conjunto de métodos de fábrica para a criação de todos os tipos de objetos de provedor de dados, tornando-a muito útil para a implementação de código de banco de dados genéricos.
A mais importante delas é a classe DbProviderFactory que fornece um mecanismo para a obtenção de uma instância IDbConnection inicial, que é o ponto de partida crítico para escrever código ADO.NET genéricos.
Cada implementação de provedor de dados padrão (exceto o SQL Server CE) inclui uma única classe factory derivada de DbProviderFactory.
A seguir temos uma relação das subclasses de DbProviderFactory:
Você pode obter uma instância da subclasse DbProviderFactory apropriada usando a classe DbProviderFactories , que é, efetivamente, uma fábrica de fábricas. Cada fábrica de provedor de dados é descrita por informações de configuração no arquivo machine.config.
Abaixo temos um exemplo para o data adatpter SQL Server. (Isto pode ser alterado ou substituído por informações de configurações específicas de aplicações se necessário.)
<configuration>
<system.data>
<DbProviderFactories>
<add name="SqlClient Data
Provider" invariant="System.Data.SqlClient"
description=".Net Framework Data Provider for
SqlServer"
type="System.Data.SqlClient.SqlClientFactory,
System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089" />
<add name="Odbc Data Provider"
... />
<add name="OleDb Data Provider"
... />
<add name="OracleClient Data
Provider" ... />
<add name="SQL Server CE Data ... />
</DbProviderFactories>
</system.data>
</configuration>
Você pode enumerar as fábricas de provedores de dados disponíveis chamando DbProviderFactories.GetFactoryClasses, que retorna uma System.Data.DataTable contendo as seguintes colunas:
Normalmente, você permitiria que o provedor fosse selecionado no momento da instalação ou na primeira vez que a aplicação fosse executada, e, em seguida, armazenaria as configurações como usuário ou como dados de configuração de aplicativo. A peça mais importante da informação é o InvariantName, que você passa para o método DbProviderFactories.GetFactory para obter a implementação DbProviderFactory que você vai usar para criar suas instâncias de IDbConnection.
Vejamos a seguir um exemplo prático que procura ilustrar como usar toda essa teoria...
Exemplo Prático
Neste exemplo vamos demonstrar a enumeração de todos os provedores de dados configurados para a máquina local e máquina e aplicação.
Ele utiliza a classe DbProviderFactories para instanciar um objeto DbProviderFactory objeto (na verdade um SqlClientFactory) a partir do qual cria o IDbConnection apropriado.
Em seguida, usamos os métodos de fábrica das interfaces de provedor de dados para criar outros objetos necessários, resultando em um código genérico.
Abra o Visual C# 2010 Express Edition e crie um novo projeto do tipo Windows Forms Application com o nome DbProviderFactory_Exemplo;
A seguir no formulário form1.cs inclua dois controles Buttons e dois controles ListBox conforme o leiaute abaixo:
![]() |
Vamos iniciar declarando os namespaces usados:
using
System;
using System.Data;
using System.Windows.Forms;
using System.Data.Common;
A sguir vamos definir o código do evento Click do botão de comando para obter a lista de provedores instalados conforme abaixo:
private void btnProvedores_Click(object sender, System.EventArgs e) { // Obtêm a lista de provedores de dados ADO.NET registros na máquina e no arquivo de configuração using (DataTable providers = DbProviderFactories.GetFactoryClasses()) { // Enumera o conjunto de provedoers de dados e exibe os detalhes lstProvedores.Items.Add("ADO.NET Data Providers Disponíveis :"); lstProvedores.Items.Add(" "); foreach (DataRow prov in providers.Rows) { lstProvedores.Items.Add(" Nome: " + prov["Name"]); lstProvedores.Items.Add(" Descrição: " + prov["Description"]); lstProvedores.Items.Add(" Nome Invariant " + prov["InvariantName"]); lstProvedores.Items.Add(""); } } } |
Executando o projeto e clicando neste botão iremos obter:
![]() |
Obs: Estes são os provedores instalados na minha máquina a sua lista pode ser diferente.
Agora vamos definir o código do evento Click do botão de comando que mostra o exemplo de acesso ao SQL Server:
private void btnAcessoDados_Click(object sender, System.EventArgs e) { // Obtêm o DbProviderFactory para o SQL Server, o provedor a usar // poderia ser selecionado pelo usuário ou lido a partir de um arquivo de configuração // Neste caso nos simplesmente pssariamos o nome invariant DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient"); // Usa o DbProviderFactory para criar o IDbConnection inicial e // então os métodos factory dos provedores de dados para os demais objetos using (IDbConnection con = factory.CreateConnection()) { // Normalmente le a string de conexão de um local seguro // Neste exemplo usamos um valor padrão con.ConnectionString = @"Data Source = .\sqlexpress;" + "Database = Northwind; Integrated Security=SSPI"; // Cria e configura um novo comando using (IDbCommand com = con.CreateCommand()) { com.CommandType = CommandType.StoredProcedure; com.CommandText = "Ten Most Expensive Products"; // Abre a conexão con.Open(); // Executa o comando e processa o resultado using (IDataReader reader = com.ExecuteReader()) { lstDados.Items.Add(Environment.NewLine); lstDados.Items.Add("Preço dos 10 Produtos mais caros."); lstDados.Items.Add(Environment.NewLine); while (reader.Read()) { // Exibe os detalhes dos produtos lstDados.Items.Add(" " + reader["TenMostExpensiveProducts"] + "\t\t" + reader["UnitPrice"]); } } } } |
No exemplo estamos acessando a consulta armazenada Ten Most Expensive Products do banco de dados Northwind.mdf.
O resultado obtido para este código é visto a seguir:
![]() |
O exemplo usado foi especifico para o SQL Server mas em um código genérico você poderia fazer assim:
1- Definir os provedores que deseja usar e que estejam disponíveis no arquivo de configuração da aplicação:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="sqlProvider" value="System.Data.SqlClient" /> <add key="oledbProvider" value="System.Data.Oledb" /> <add key="MySqlProvider" value="System.Data.MySqlClient" /> <add key="OdbcProvider" value="System.Data.Odbc" /> </appSettings> </configuration> |
2- Ler o provedor de dados específico e obter o seu nome invariante, criar o DbProviderFactory, criar a string de conexão e montar a string de conexão conforme o provedor.
string sInvariant = ConfigurationManager.AppSettings["oledbProvider"]; DbProviderFactory df = DbProviderFactories.GetFactory(sInvariant); DbConnectionStringBuilder csb = df.CreateConnectionStringBuilder(); string paramName = string.Empty; switch (sInvariant) { case "System.Data.SqlClient": csb.Add("Data Source", "localhost"); csb.Add("Initial Catalog", "Northwind"); csb.Add("Integrated Security", "SSPI"); paramName = "@nomeparametro"; break; case "System.Data.OleDb": csb.Add("Provider", "SQLOLEDB"); csb.Add("Data Source", "localhost"); csb.Add("Initial Catalog", "Northwind"); csb.Add("Integrated Security", "SSPI"); paramName = "?"; break; case "System.Data.Odbc": csb.Add("Driver", "{SQL Server}"); csb.Add("Server", "localhost"); csb.Add("Database", "Northwind"); csb.Add("Trusted_Connection", "yes"); paramName = "?"; break; default: return; break; } |
Este é apenas uma indicação de como fazer mas existem outras maneiras de se obter o mesmo resultado.
Aguarde que em outro artigo irei criar um exemplo completo sobre este assunto usando a linguagem C#.
Pegue o projeto completo aqui :
DbProviderFactory_Exemplo.zip
1Timóteo 2:5
Porque há um só Deus, e um só Mediador entre Deus e os homens, Cristo Jesus, homem,Referências: