Compartilhar via


Definir as configurações de nível de conexão e comando da Camada de Acesso a Dados (VB)

por Scott Mitchell

Baixar PDF

Os TableAdapters em um Dataset Tipado automaticamente gerenciam a conexão com o banco de dados, emitem comandos e preenchem um DataTable com os resultados. No entanto, há ocasiões em que queremos cuidar desses detalhes e, neste tutorial, aprendemos a acessar as configurações de conexão e nível de comando do banco de dados no TableAdapter.

Introdução

Ao longo da série de tutoriais, usamos Conjuntos de Dados Tipados para implementar a Camada de Acesso a Dados e objetos de negócios de nossa arquitetura em camadas. Conforme discutido no primeiro tutorial, os DataTables do Conjunto de Dados Tipados servem como repositórios de dados, enquanto os TableAdapters atuam como wrappers para se comunicar com o banco de dados para recuperar e modificar os dados subjacentes. Os TableAdapters encapsulam a complexidade envolvida no trabalho com o banco de dados e nos salvam de ter que escrever código para se conectar ao banco de dados, emitir um comando ou preencher os resultados em uma DataTable.

Há momentos, no entanto, em que precisamos entrar nas profundezas do TableAdapter e escrever código que funciona diretamente com os objetos ADO.NET. No tutorial Encapsular Modificações de Banco de Dados em uma Transação, por exemplo, adicionamos métodos ao TableAdapter para iniciar, confirmar e reverter transações ADO.NET. Esses métodos usaram um objeto interno, criado manualmente SqlTransaction, que foi atribuído aos objetos TableAdapter.

Neste tutorial, examinaremos como acessar as configurações de conexão e nível de comando do banco de dados no TableAdapter. Em particular, adicionaremos funcionalidades ao ProductsTableAdapter que permitem o acesso à cadeia de conexão subjacente e às configurações de tempo de espera de comando.

Trabalhando com dados usando ADO.NET

O Microsoft .NET Framework contém uma infinidade de classes projetadas especificamente para trabalhar com dados. Essas classes, encontradas no System.Data namespace, são conhecidas como classes ADO.NET . Algumas das classes sob o guarda-chuva ADO.NET estão vinculadas a um provedor de dados específico. Você pode pensar em um provedor de dados como um canal de comunicação que permite que as informações fluam entre as classes ADO.NET e o armazenamento de dados subjacente. Há provedores generalizados, como OleDb e ODBC, bem como provedores que são especialmente projetados para um sistema de banco de dados específico. Por exemplo, embora seja possível se conectar a um banco de dados do Microsoft SQL Server usando o provedor OleDb, o provedor sqlClient é muito mais eficiente, pois foi projetado e otimizado especificamente para o SQL Server.

Ao acessar dados programaticamente, o seguinte padrão é comumente usado:

  1. Estabeleça uma conexão com o banco de dados.
  2. Emita um comando.
  3. Para SELECT consultas, trabalhe com os registros obtidos.

Há classes ADO.NET separadas para executar cada uma dessas etapas. Para se conectar a um banco de dados usando o provedor SqlClient, por exemplo, use a SqlConnection classe. Para emitir um comando INSERT, UPDATE, DELETE ou SELECT para o banco de dados, use a classe SqlCommand.

Com exceção do Tutorial de Encapsulamento de Modificações de Banco de Dados em uma Transação, não tivemos que escrever qualquer código ADO.NET de baixo nível porque o código gerado automaticamente pelos TableAdapters inclui a funcionalidade necessária para se conectar ao banco de dados, emitir comandos, recuperar dados e preencher tabelas de dados no DataTables. No entanto, pode haver momentos em que precisamos personalizar essas configurações de baixo nível. Nas próximas etapas, examinaremos como explorar os objetos ADO.NET usados internamente pelos TableAdapters.

Etapa 1: Examinando com a propriedade de conexão

Cada classe TableAdapter tem uma Connection propriedade que especifica informações de conexão de banco de dados. O tipo de dados dessa propriedade e o valor ConnectionString são determinados pelas seleções feitas no Assistente de Configuração do TableAdapter. Lembre-se de que quando adicionamos pela primeira vez um TableAdapter a um Conjunto de Dados Tipado, esse assistente nos solicita a fonte do banco de dados (consulte a Figura 1). A lista suspensa nesta primeira etapa inclui os bancos de dados especificados no arquivo de configuração, bem como quaisquer outros bancos de dados nas Conexões de Dados do Explorador de Servidores. Se o banco de dados que desejamos usar não existir na lista suspensa, uma nova conexão de banco de dados poderá ser especificada clicando no botão Nova Conexão e fornecendo as informações de conexão necessárias.

A primeira etapa do Assistente de Configuração do TableAdapter

Figura 1: a primeira etapa do Assistente de Configuração do TableAdapter (clique para exibir a imagem em tamanho real)

Vamos dedicar um momento para verificar o código da propriedade do TableAdapter. Conforme observado no tutorial Criando uma Camada de Acesso a Dados , podemos exibir o código TableAdapter gerado automaticamente acessando a janela Exibição de Classe, fazendo drill down para a classe apropriada e clicando duas vezes no nome do membro.

Navegue até a janela Exibição de Classe acessando o menu Exibir e escolhendo Exibição de Classe (ou digitando Ctrl+Shift+C). Na metade superior da janela Exibição de Classe, expanda o namespace NorthwindTableAdapters e selecione a classe ProductsTableAdapter. Isso exibirá os membros de ProductsTableAdapter na metade inferior do Modo de Exibição de Classe, conforme mostrado na Figura 2. Clique duas vezes na Connection propriedade para ver seu código.

Double-Click a propriedade Connection na exibição de Classe para visualizar seu código gerado automaticamente

Figura 2: Double-Click a propriedade de conexão na exibição de classe para visualizar seu código gerado automaticamente

A propriedade TableAdapter s Connection e outro código relacionado à conexão seguem:

Private _connection As System.Data.SqlClient.SqlConnection
Private Sub InitConnection()
    Me._connection = New System.Data.SqlClient.SqlConnection
    Me._connection.ConnectionString = _
        ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
End Sub
Friend Property Connection() As System.Data.SqlClient.SqlConnection
    Get
        If (Me._connection Is Nothing) Then
            Me.InitConnection
        End If
        Return Me._connection
    End Get
    Set
        Me._connection = value
        If (Not (Me.Adapter.InsertCommand) Is Nothing) Then
            Me.Adapter.InsertCommand.Connection = value
        End If
        If (Not (Me.Adapter.DeleteCommand) Is Nothing) Then
            Me.Adapter.DeleteCommand.Connection = value
        End If
        If (Not (Me.Adapter.UpdateCommand) Is Nothing) Then
            Me.Adapter.UpdateCommand.Connection = value
        End If
        Dim i As Integer = 0
        Do While (i < Me.CommandCollection.Length)
            If (Not (Me.CommandCollection(i)) Is Nothing) Then
                CType(Me.CommandCollection(i), _
                    System.Data.SqlClient.SqlCommand).Connection = value
            End If
            i = (i + 1)
        Loop
    End Set
End Property

Quando a classe TableAdapter é instanciada, a variável _connection de membro é igual a Nothing. Quando a Connection propriedade é acessada, ela verifica primeiro se a _connection variável de membro foi instanciada. Se não tiver sido feito, o método InitConnection será invocado para instanciar _connection e definir sua propriedade ConnectionString como o valor da string de conexão especificado na primeira etapa do assistente de configuração do TableAdapter.

A Connection propriedade também pode ser atribuída a um SqlConnection objeto. Isso associa o novo SqlConnection objeto a cada um dos objetos do SqlCommand TableAdapter.

Etapa 2: Expondo configurações de Connection-Level

As informações de conexão devem permanecer encapsuladas no TableAdapter e não estar acessíveis a outras camadas na arquitetura do aplicativo. No entanto, pode haver cenários em que as informações de nível de conexão do TableAdapter precisem ser acessíveis ou personalizáveis para uma consulta, usuário ou página ASP.NET.

Vamos estender o ProductsTableAdapter no Northwind Conjunto de Dados para incluir uma ConnectionString propriedade que pode ser usada pela Camada de Lógica de Negócios para ler ou alterar a cadeia de conexão usada pelo TableAdapter.

Observação

Uma cadeia de conexão é uma cadeia de caracteres que especifica informações de conexão de banco de dados, como o provedor a ser usado, o local do banco de dados, as credenciais de autenticação e outras configurações relacionadas ao banco de dados. Para obter uma lista de padrões de cadeia de conexão usados por uma variedade de armazenamentos de dados e provedores, consulte ConnectionStrings.com.

Conforme discutido no tutorial Criando uma Camada de Acesso a Dados , as classes geradas automaticamente pelo Conjunto de Dados Tipados podem ser estendidas por meio do uso de classes parciais. Primeiro, crie uma nova subpasta no projeto nomeado ConnectionAndCommandSettings abaixo da ~/App_Code/DAL pasta.

Adicionar uma subpasta chamada ConnectionAndCommandSettings

Figura 3: Adicionar uma subpasta nomeada ConnectionAndCommandSettings

Adicione um novo arquivo de classe nomeado ProductsTableAdapter.ConnectionAndCommandSettings.vb e insira o seguinte código:

Namespace NorthwindTableAdapters
    Partial Public Class ProductsTableAdapter
        Public Property ConnectionString() As String
            Get
                Return Me.Connection.ConnectionString
            End Get
            Set(ByVal value As String)
                Me.Connection.ConnectionString = value
            End Set
        End Property
    End Class
End Namespace

Essa classe parcial adiciona uma Public propriedade nomeada ConnectionString à ProductsTableAdapter classe que permite que qualquer camada leia ou atualize a cadeia de conexão para a conexão subjacente do TableAdapter.

Com essa classe parcial criada (e salva), abra a ProductsBLL classe. Vá para um dos métodos existentes e digite Adapter, então pressione a tecla de ponto para exibir o IntelliSense. Você deve ver a nova ConnectionString propriedade disponível no IntelliSense, o que significa que você pode ler ou ajustar esse valor programaticamente da BLL.

Expondo o objeto Conexão inteiro

Essa classe parcial expõe apenas uma propriedade do objeto de conexão subjacente: ConnectionString. Se você quiser disponibilizar todo o objeto de conexão fora dos limites do TableAdapter, você pode alternativamente alterar o nível de proteção da propriedade Connection. O código gerado automaticamente que examinamos na Etapa 1 mostrou que a propriedade TableAdapter s Connection está marcada como Friend, o que significa que ela só pode ser acessada por classes no mesmo assembly. No entanto, isso pode ser alterado por meio da propriedade TableAdapterConnectionModifier.

Abra o Northwind DataSet, clique no ProductsTableAdapter Designer e navegue até a janela de Propriedades. Lá, você verá o ConnectionModifier configurado para seu valor padrão, Assembly. Para disponibilizar a propriedade Connection fora do assembly do Conjunto de Dados Tipado, altere a propriedade ConnectionModifier para Public.

O nível de acessibilidade da propriedade connection pode ser configurado por meio da propriedade ConnectionModifier

Figura 4: O Connection nível de acessibilidade da propriedade pode ser configurado por meio da ConnectionModifier propriedade (clique para exibir a imagem em tamanho real)

Salve o DataSet e retorne à ProductsBLL classe. Como antes, vá para um dos métodos existentes e digite Adapter, em seguida, pressione a tecla de ponto para abrir o IntelliSense. A lista deve incluir uma Connection propriedade, o que significa que agora você pode ler ou atribuir programaticamente as configurações de nível de conexão da BLL.

Um TableAdapter consiste em uma consulta principal que, por padrão, tem instruções INSERT, UPDATE e DELETE geradas automaticamente. Essas instruções INSERT, UPDATE e DELETE são implementadas como um objeto adaptador de dados ADO.NET através da propriedade Adapter no código do TableAdapter. Assim como com sua Connection propriedade, o Adapter tipo de dados da propriedade é determinado pelo provedor de dados usado. Como esses tutoriais usam o provedor sqlClient, a Adapter propriedade é do tipo SqlDataAdapter.

A propriedade do TableAdapter Adapter possui três propriedades do tipo SqlCommand que ele usa para emitir as instruções INSERT, UPDATE e DELETE.

  • InsertCommand
  • UpdateCommand
  • DeleteCommand

Um SqlCommand objeto é responsável por enviar uma consulta específica para o banco de dados e tem propriedades como: CommandText, que contém a instrução SQL ad hoc ou o procedimento armazenado a ser executado; e Parameters, que é uma coleção de SqlParameter objetos. Como vimos no tutorial Criando uma Camada de Acesso a Dados , esses objetos de comando podem ser personalizados por meio da janela Propriedades.

Além de sua consulta principal, o TableAdapter pode incluir um número variável de métodos que, quando invocados, expedim um comando especificado para o banco de dados. O objeto de comando da consulta principal e os objetos de comando para todos os métodos adicionais são armazenados na propriedade TableAdapter s CommandCollection .

Vamos reservar um momento para examinar o código gerado pelo ProductsTableAdapter no Northwind DataSet para essas duas propriedades e suas variáveis de membro de suporte e métodos auxiliares.

Private WithEvents _adapter As System.Data.SqlClient.SqlDataAdapter
Private Sub InitAdapter()
    Me._adapter = New System.Data.SqlClient.SqlDataAdapter
    
    ... Code that creates the InsertCommand, UpdateCommand, ...
    ... and DeleteCommand instances - omitted for brevity ...
End Sub
Private ReadOnly Property Adapter() As System.Data.SqlClient.SqlDataAdapter
    Get
        If (Me._adapter Is Nothing) Then
            Me.InitAdapter
        End If
        Return Me._adapter
    End Get
End Property
Private _commandCollection() As System.Data.SqlClient.SqlCommand
Private Sub InitCommandCollection()
    Me._commandCollection = New System.Data.SqlClient.SqlCommand(8) {}
    ... Code that creates the command objects for the main query and the ...
    ... ProductsTableAdapter�s other eight methods - omitted for brevity ...
End Sub
Protected ReadOnly Property CommandCollection() As System.Data.SqlClient.SqlCommand()
    Get
        If (Me._commandCollection Is Nothing) Then
            Me.InitCommandCollection
        End If
        Return Me._commandCollection
    End Get
End Property

O código para as propriedades Adapter e CommandCollection imita de perto a da propriedade Connection. Há variáveis de membro que contêm os objetos usados pelas propriedades. Os acessadores de propriedades Get começam verificando se a variável de membro correspondente é Nothing. Nesse caso, um método de inicialização é chamado, que cria uma instância da variável de membro e atribui as propriedades principais relacionadas ao comando.

Etapa 4: Expondo configurações de Command-Level

O ideal é que as informações no nível de comando permaneçam encapsuladas na Camada de Acesso a Dados. Se essas informações forem necessárias em outras camadas da arquitetura, no entanto, elas poderão ser expostas por meio de uma classe parcial, assim como nas configurações de nível de conexão.

Como o TableAdapter tem apenas uma única Connection propriedade, o código para expor as configurações de nível de conexão é bastante simples. As coisas são um pouco mais complicadas ao modificar as configurações de nível de comando porque o TableAdapter pode ter vários objetos de comando - um InsertCommand, UpdateCommande DeleteCommand, juntamente com um número variável de objetos de comando na CommandCollection propriedade. Ao atualizar as configurações de nível de comando, essas configurações precisarão ser propagadas para todos os objetos de comando.

Por exemplo, imagine que havia determinadas consultas no TableAdapter que demoraram muito tempo para serem executadas. Ao usar o TableAdapter para executar uma dessas consultas, convém aumentar a propriedade do objeto de CommandTimeoutcomando. Essa propriedade especifica o número de segundos para aguardar a execução do comando e o padrão é 30.

Para permitir que a CommandTimeout propriedade seja ajustada pela BLL, adicione o seguinte Public método ao uso do ProductsDataTable arquivo de classe parcial criado na Etapa 2 (ProductsTableAdapter.ConnectionAndCommandSettings.vb):

Public Sub SetCommandTimeout(ByVal timeout As Integer)
    If Me.Adapter.InsertCommand IsNot Nothing Then
        Me.Adapter.InsertCommand.CommandTimeout = timeout
    End If
    If Me.Adapter.DeleteCommand IsNot Nothing Then
        Me.Adapter.DeleteCommand.CommandTimeout = timeout
    End If
    If Me.Adapter.UpdateCommand IsNot Nothing Then
        Me.Adapter.UpdateCommand.CommandTimeout = timeout
    End If
    For i As Integer = 0 To Me.CommandCollection.Length - 1
        If Me.CommandCollection(i) IsNot Nothing Then
            Me.CommandCollection(i).CommandTimeout = timeout
        End If
    Next
End Sub

Esse método pode ser invocado a partir da BLL ou da Camada de Apresentação para definir o tempo limite de execução de comandos para todos os comandos realizados por essa instância do TableAdapter.

Observação

As propriedades Adapter e CommandCollection são marcadas como Private, o que significa que elas só podem ser acessadas a partir do código dentro do TableAdapter. Ao contrário da Connection propriedade, esses modificadores de acesso não são configuráveis. Portanto, se você precisar expor propriedades de nível de comando a outras camadas na arquitetura, deverá usar a abordagem de classe parcial discutida acima para fornecer um Public método ou propriedade que lê ou grava nos Private objetos de comando.

Resumo

Os TableAdapters em um Conjunto de Dados Tipado servem para encapsular detalhes de acesso a dados e complexidade. Usando TableAdapters, não precisamos nos preocupar em escrever ADO.NET código para se conectar ao banco de dados, emitir um comando ou preencher os resultados em uma DataTable. Tudo é tratado automaticamente para nós.

No entanto, pode haver momentos em que precisamos personalizar as especificidades de ADO.NET de baixo nível, como alterar a cadeia de conexão ou os valores padrão de tempo limite de conexão ou comando. O TableAdapter tem propriedades Connection, Adapter e CommandCollection geradas automaticamente, mas elas são, por padrão, Friend ou Private. Essas informações internas podem ser expostas estendendo o TableAdapter usando classes parciais para incluir Public métodos ou propriedades. Como alternativa, o modificador de acesso à propriedade TableAdapter Connection pode ser configurado por meio da propriedade TableAdapter s ConnectionModifier .

Divirta-se programando!

Sobre o autor

Scott Mitchell, autor de sete livros asp/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 Horas. Ele pode ser alcançado em mitchell@4GuysFromRolla.com.

Agradecimentos Especiais a

Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial foram Burnadette Leigh, S ren Jacob Lauritsen, Teresa Murphy e Hilton Geisenow. Interessado em revisar meus próximos artigos do MSDN? Se assim for, deixe-me uma linha em mitchell@4GuysFromRolla.com.