Usando factories de Provedores
Dentre as inúmeras novidades que a plataforma .NET trouxe na versão 2.0 com relação ao acesso a dados, temos o novo conceito de provider e de factory.
Usando factories de Provedores
José Carlos Macoratti (e-mail) é referência em Visual Basic no Brasil e autor dos livros "Aprenda Rápido: ASP" e "ASP, ADO e Banco de Dados na Internet". Mantenedor do site macoratti.net.
Dentre as inúmeras novidades que a plataforma .NET trouxe na versão 2.0 com relação ao acesso a dados, temos o novo conceito de provider e de factory.
Até o momento, quando pretendíamos efetuar uma conexão com uma base de dados, criávamos os objetos diretamente. Assim, para acessar o SQL Server, usávamos as classes SqlConnection, SqlDataAdapter, SqlXXX; para acessar uma base de dados Access usávamos os provedores OleDbConnection, OleDbDataAdapater, OleDbCommand, OleDbXXX, e assim por diante; ou seja, tínhamos uma série de classes específicas de provedores que eram usadas conforme a fonte de dados a ser acessada.
O problema é quando desejamos poder acessar tanto uma base SQL Server, como uma base Oracle ou Access usando código genérico. Isto era possível pois cada classe implementava uma interface genérica IDbConnection, IDbDataAdapter, IDbCommand, etc.
O novo modelo de provedor ADO.NET 2.0 esta baseado em um série de classes base no namespace System.Data.Comom. A classe DBProviderFactories permite a realização de dois tipos de tarefas:
01. Obter uma lista de todos os provedores existentes, via método estático GetFactoryClasses;
02. Criar uma instância de um determinado Factory conforme o seu tipo, via método GetFactoryClass;
Uma classe base de provedor é um objeto factory que é usado para criar um conjunto de objetos relacionados como SqlConnection e SqlCommand. Eles retornam um tipo de classe abstrata do tipo DBConnection. As classes de provider factory são derivadas de uma classe base abstrata: System.Data.Common.DbProviderFactory, e, para cada tipo de base de dados a ser acessado, temos uma nova classe derivada desta classe base abstrata. A classe DbDataProvider define o número de funções que esta subclasse precisa implementar:
CreateComand() |
Cria um objeto Command derivado de DBCommand. |
CreateCommandBuilder() |
Cria um objeto derivado de DbCommandBuilder |
CreateConnection() |
Cria um objeto derivado de DbConnection. |
CreateConnectionStringBuilder() |
Cria um objeto derivado de DbConnectionStringBuilder |
CreateDataAdapter() |
Cria um objeto derivado de DbDataAdapter. |
CreateDataSourceEnumerator() |
Cria um objeto derivado de DbDataSourceEnumerator. |
CreateParameter() |
Cria um objeto derivado de DbParameter. |
CreatePermission() |
Cria um objeto derivado de CodeAccessPermission, |
Funções DbDataProvider |
Desde que o DbProviderFactory apropriado foi criado, a função na tabela acima pode ser usada para criar o objeto apropriado ao invés de usar o operador New, como anteriormente. (Para determinar todas as classes DbProviderFactory disponíveis e criar suas classes adicionais é fornecido a classe System.Data.Common.DbProviderFactories).
Cada provedor de dados faz o registro de uma classe ProviderFactory no arquivo machine.config da plataforma .NET. A classe base DbProviderFactory e a classe ProviderFactories podem retornar um DataTable de informações sobre os diferentes provedores registrados no arquivo machine.config, e podem recuperar a ProviderFactory conforme a sequência do provedor fornecida ou um DataRow de um DataTable.
Com base nisto podemos descobrir quais os provedores de dados instalados usando o código abaixo:
Imports System.Data.common
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim factory As DbProviderFactory = Nothing
Dim dtFactories As DataTable = DbProviderFactories.GetFactoryClasses()
Dim vetor As ArrayList = New ArrayList
Dim i As Integer = 0
For Each drFactory As DataRow In dtFactories.Rows
Try
factory = DbProviderFactories.GetFactory(drFactory)
vetor.Add(factory)
ListBox1.Items.Add(vetor(i))
i = i + 1
Catch ex As Exception
factory = Nothing
End Try
Next
End Sub
End Class
Exibindo os provedores de dados instalados
No código acima, DbProviderFactories.GetFactoryClasses() retorna um DataTabe com todos os possíveis provedores de dados.
Usamos DbProviderFactories.GetFactory para criar um DbProviderFactory baseado no nome da DataRow do DataTable obtido acima.
Poderíamos usar o código abaixo para tentar efetuar a conexão com a base de dados MSDE. Como o provedor de dados é o Data.SqlClient, haveria 3 tentativas frustradas com exibição de mensagem de erros, pois a string de conexão usada refere-se ao provedor SqlClient que é o último data provider registrado no machine.config.
Imports System.Data.common
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim factory As DbProviderFactory = Nothing
Dim conn As DbConnection = Nothing
Dim dtFactories As DataTable = DbProviderFactories.GetFactoryClasses()
Dim i As Integer = 0
For Each drFactory As DataRow In dtFactories.Rows
Try
factory = DbProviderFactories.GetFactory(drFactory)
conn = factory.CreateConnection()
conn.ConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind; _
User ID=sa;password=;Data Source=MACORATI\VSDOTNET"
conn.Open()
conn.Close()
conn = Nothing
Exit For
Catch ex As Exception
conn = Nothing
factory = Nothing
MsgBox(ex.Message)
End Try
Next
End Sub
End Class
Vamos mostrar um exemplo onde iremos trabalhar com classes de uma base de dados sem definirmos o tipo das classes. Vamos preencher um DataGridViw com os dados da tabela Orders do banco de dados Northwind do MSDE (compatível com SQL Server).
Obs: Utilize uma string de conexão compatível com a sua base de dados.
Crie um novo projeto no Visual Basic 2005 Express com o nome de acessoBD, e, no formulário principal, inclua um componente DataGridView (dgv1) e um botão de comando (btnPreencherGrid), conforme figura abaixo:
Defina o seguinte import no código :
Imports System.Data.Common
Agora, clique duas vezes no botão de comando do formulário e inclua o seguinte código:
Private Sub btnPreencherGrid_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreencherGrid.Click
Dim provider As String = "System.Data.SqlClient"
Dim factory As DbProviderFactory = DbProviderFactories.GetFactory(provider)
Dim cnn As DbConnection = factory.CreateConnection
cnn.ConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;User ID=sa;password=;Data Source=MACORATI\VSDOTNET"
Dim cmd As DbCommand = factory.CreateCommand
cmd.Connection = cnn
cmd.CommandText = "select * from Orders"
cmd.CommandType = CommandType.Text
cnn.Open()
Dim reader As DbDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
Dim info As DataTable = New DataTable
info.Load(reader)
reader.Close()
dgv1.DataSource = info
End Sub
Nota: Poderíamos ter armazenado a string de conexão e a informação do provedor de dados no arquivo de configuração web.config:
Para obter os valores do web.config teríamos que usar o seguinte código:
Dim dbfactory As DbProviderFactory = DbProviderFactories.GetFactory(ConfigurationSettings.AppSettings.Get("DbProvider"))
dbconn.ConnectionString = ConfigurationSettings.AppSettings.Get("ConnectionString")
Este exemplo ilustra como você pode trabalhar com as classes de uma base de dados sem especificar o tipo das classes; perceba que, embora eu esteja acessando uma base de dados MSDE (compatível com SQL Server), e que usa a classe SQLClient, eu não precisei especificar nada a respeito desta classe.
As classes do tipo Factory são capazes de criar os objetos associados que permitem o acesso a base de dados. Foi necessário apenas definir o provedor na linha de código :
Dim provider As String = "System.Data.SqlClient"
A seguir, usando o método GetFactory, criamos um DbProviderFactory baseado no provedor fornecido acima.
Dim factory As DbProviderFactory = DbProviderFactories.GetFactory(provider)
Dim cnn As DbConnection = factory.CreateConnection
Observe que criamos um DataReader e preenchemos o um DataTable usando o método Load.
Dim info As DataTable = New DataTable
info.Load(reader)
Executando o projeto teremos o seguinte resultado:
Pegue o código do projeto aqui: acessoBD.zip
Até breve!
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo