Condividi tramite


Configurazione delle impostazioni del livello di accesso ai dati a livello di connessione e di comando (VB)

di Scott Mitchell

Scaricare il PDF

Gli oggetti TableAdapter all'interno di un dataset tipizzato si occupano automaticamente della connessione al database, dell'esecuzione di comandi e del popolamento di una tabella DataTable con i risultati. Ci sono tuttavia occasioni in cui vogliamo occuparci personalmente di questi dettagli, e in questo tutorial impariamo come accedere alle impostazioni della connessione al database e a livello di comando nel TableAdapter.

Introduzione

In tutta la serie di esercitazioni sono stati usati set di dati tipizzati per implementare il livello di accesso ai dati e gli oggetti business dell'architettura a più livelli. Come illustrato nella prima esercitazione, le tabelle DataTable del dataset tipizzato fungono da repository di dati, mentre i TableAdapter fungono da wrapper per comunicare con il database per recuperare e modificare i dati sottostanti. Gli oggetti TableAdapter incapsulano la complessità dell'uso del database e consentono di evitare la necessità di scrivere codice per connettersi al database, eseguire un comando o popolare i risultati in un oggetto DataTable.

In alcuni casi, tuttavia, è necessario scavare nelle profondità dell'oggetto TableAdapter e scrivere codice che funziona direttamente con gli oggetti ADO.NET. Nell'esercitazione Inserire le modifiche al database all'interno di una transazione, ad esempio, sono stati aggiunti metodi al TableAdapter per iniziare, completare e annullare le transazioni ADO.NET. Questi metodi utilizzavano un oggetto interno creato manualmente che veniva assegnato agli oggetti di TableAdapter SqlTransaction.

In questa esercitazione verrà illustrato come accedere alle impostazioni a livello di comando e connessione del database in TableAdapter. In particolare, si aggiungeranno funzionalità a ProductsTableAdapter che consente l'accesso alla stringa di connessione sottostante e alle impostazioni di timeout dei comandi.

Utilizzo dei dati tramite ADO.NET

Microsoft .NET Framework contiene una pletora di classi progettate appositamente per lavorare con i dati. Queste classi, trovate all'interno del namespaceSystem.Data, vengono definite classi ADO.NET. Alcune classi sotto l'ombrello ADO.NET sono associate a un provider di dati specifico. È possibile considerare un provider di dati come un canale di comunicazione che consente il flusso delle informazioni tra le classi ADO.NET e l'archivio dati sottostante. Esistono provider generalizzati, come OleDb e ODBC, nonché provider appositamente progettati per un particolare sistema di database. Ad esempio, sebbene sia possibile connettersi a un database di Microsoft SQL Server usando il provider OleDb, il provider SqlClient è molto più efficiente perché è stato progettato e ottimizzato in modo specifico per SQL Server.

Quando si accede ai dati a livello di codice, viene comunemente usato il modello seguente:

  1. Stabilire una connessione al database.
  2. Eseguire un comando.
  3. Per SELECT query, usare i record risultanti.

Esistono classi ADO.NET separate per l'esecuzione di ognuno di questi passaggi. Per connettersi a un database usando il provider SqlClient, ad esempio, usare la SqlConnection classe . Per eseguire un INSERTcomando , UPDATE, DELETEo SELECT al database, usare la SqlCommand classe .

Ad eccezione del modifiche al database all'interno di una transazione tutorial, non è stato necessario scrivere codice di basso livello Ado.NET perché il codice generato automaticamente dai TableAdapters include le funzionalità necessarie per la connessione al database, eseguire comandi, recuperare dati e popolare questi dati in DataTables. Tuttavia, potrebbero verificarsi momenti in cui è necessario personalizzare queste impostazioni di basso livello. Nei passaggi successivi si esaminerà come accedere agli oggetti ADO.NET usati internamente dagli oggetti TableAdapter.

Passaggio 1: Esame della proprietà di connessione

Ogni classe TableAdapter ha una Connection proprietà che specifica le informazioni di connessione al database. Il tipo di dati e il valore di questa proprietà sono determinati dalle selezioni effettuate nella procedura guidata di configurazione del TableAdapter. Tenere presente che quando si aggiunge per la prima volta un oggetto TableAdapter a un dataset tipizzato, questa procedura guidata richiede l'origine del database (vedere la figura 1). L'elenco a discesa di questo primo passaggio include i database specificati nel file di configurazione e tutti gli altri database nelle connessioni dati di Esplora server. Se il database che si desidera utilizzare non esiste nell'elenco a discesa, è possibile specificare una nuova connessione al database facendo clic sul pulsante Nuova connessione e specificando le informazioni di connessione necessarie.

Primo passaggio della Configurazione Guidata TableAdapter

Figura 1: Primo passaggio della Configurazione guidata TableAdapter (fare clic per visualizzare l'immagine a dimensione intera)

Prendiamo un momento per esaminare il codice per la proprietà del TableAdapter.Connection Come indicato nell'esercitazione Creazione di un livello di accesso ai dati , è possibile visualizzare il codice TableAdapter generato automaticamente passando alla finestra Visualizzazione classi, eseguendo il drill-down alla classe appropriata e quindi facendo doppio clic sul nome del membro.

Passare alla finestra Visualizzazione classi passando al menu Visualizza e scegliendo Visualizzazione classi (o digitando CTRL+MAIUSC+C). Dalla parte superiore della finestra Visualizzazione Classi, eseguire il drill-down nello spazio dei nomi NorthwindTableAdapters e selezionare la classe ProductsTableAdapter. Verranno visualizzati i membri di ProductsTableAdapter nella metà inferiore della Visualizzazione Classi, come illustrato nella figura 2. Fare doppio clic sulla proprietà per visualizzarne il Connection codice.

Double-Click la proprietà Connection nella visualizzazione Classi per visualizzare il codice generato automaticamente

Figura 2: Double-Click la proprietà Connection nella vista Classi per visualizzare il codice generato automaticamente

La proprietà tableAdapter Connection e altri codici correlati alla connessione sono i seguenti:

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 viene creata un'istanza della classe TableAdapter, la variabile membro _connection è uguale a Nothing. Quando si accede alla proprietà Connection, si verifica prima se la variabile membro _connection è stata inizializzata. In caso contrario, viene richiamato il metodo InitConnection, che crea un'istanza _connection e imposta la relativa proprietà ConnectionString sul valore della stringa di connessione specificato dal primo passaggio della Configurazione guidata TableAdapter.

La Connection proprietà può anche essere assegnata a un SqlConnection oggetto . In questo modo, il nuovo SqlConnection oggetto viene associato a ognuno degli oggetti TableAdapter SqlCommand .

Passaggio 2: Esposizione delle impostazioni di Connection-Level

Le informazioni di connessione devono rimanere incapsulate all'interno di TableAdapter e non essere accessibili ad altri livelli nell'architettura dell'applicazione. Tuttavia, possono verificarsi scenari in cui le informazioni a livello di connessione di TableAdapter devono essere accessibili o personalizzabili per una query, un utente o una pagina ASP.NET.

Dobbiamo estendere il ProductsTableAdapter nel Northwind DataSet per includere una proprietà ConnectionString che può essere utilizzata dal livello logico aziendale per leggere o modificare la stringa di connessione utilizzata dal TableAdapter.

Annotazioni

Una stringa di connessione è una stringa che specifica le informazioni di connessione al database, ad esempio il provider da usare, il percorso del database, le credenziali di autenticazione e altre impostazioni correlate al database. Per un elenco dei modelli di stringa di connessione usati da diversi archivi dati e provider, vedere ConnectionStrings.com.

Come illustrato nell'esercitazione Creazione di un livello di accesso ai dati , è possibile estendere le classi generate automaticamente di DataSet tipizzato tramite l'uso di classi parziali. Creare prima di tutto una nuova sottocartella nel progetto denominato ConnectionAndCommandSettings sotto la ~/App_Code/DAL cartella .

Aggiungere una sottocartella denominata ConnectionAndCommandSettings

Figura 3: Aggiungere una sottocartella denominata ConnectionAndCommandSettings

Aggiungere un nuovo file di classe denominato ProductsTableAdapter.ConnectionAndCommandSettings.vb e immettere il codice seguente:

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

Questa classe parziale aggiunge una Public proprietà denominata ConnectionString alla ProductsTableAdapter classe che consente a qualsiasi livello di leggere o aggiornare la stringa di connessione per la connessione sottostante di TableAdapter.

Con questa classe parziale creata (e salvata), aprire la ProductsBLL classe . Passare a uno dei metodi esistenti e digitare Adapter, quindi premere il tasto punto per visualizzare IntelliSense. Dovrebbe essere visualizzata la nuova ConnectionString proprietà disponibile in IntelliSense, ovvero è possibile leggere o modificare questo valore a livello di codice dal BLL.

Esposizione dell'intero oggetto connessione

Questa classe parziale espone una sola proprietà dell'oggetto connessione sottostante: ConnectionString. Se si desidera rendere disponibile l'oggetto di connessione completo oltre i limiti dell'oggetto TableAdapter, in alternativa, è possibile modificare il livello di protezione della proprietà Connection. Il codice generato automaticamente esaminato nel passaggio 1 ha mostrato che la proprietà TableAdapter s Connection è contrassegnata come Friend, ovvero è accessibile solo dalle classi nello stesso assembly. Questa operazione può essere modificata, tuttavia, tramite la proprietà TableAdapter.ConnectionModifier

Aprire il Northwind set di dati, fare clic su ProductsTableAdapter in Progettazione e passare alla finestra Proprietà. Verrà visualizzato il ConnectionModifier impostato sul suo valore predefinito, Assembly. Per rendere disponibile all'esterno dell'assembly del DataSet tipizzato la proprietà Connection, cambiare la proprietà ConnectionModifier in Public.

Il livello di accessibilità della proprietà di connessione può essere configurato tramite la proprietà ConnectionModifier

Figura 4: Il Connection livello di accessibilità della proprietà può essere configurato tramite la proprietà (ConnectionModifier a dimensione intera)

Salvare l'oggetto DataSet e quindi tornare alla ProductsBLL classe . Come in precedenza, passare a uno dei metodi esistenti e digitare Adapter e quindi premere la chiave del punto per visualizzare IntelliSense. L'elenco deve includere una Connection proprietà, ovvero è ora possibile leggere o assegnare a livello di codice le impostazioni a livello di connessione dal BLL.

Un oggetto TableAdapter è costituito da una query principale che, per impostazione predefinita, ha istruzioni INSERT, UPDATE e DELETE generate automaticamente. Le istruzioni INSERT, UPDATE e DELETE della query principale vengono implementate nel codice di TableAdapter come oggetto adattatore dati ADO.NET tramite la proprietà Adapter. Analogamente alla relativa Connection proprietà, il Adapter tipo di dati della proprietà viene determinato dal provider di dati usato. Poiché queste esercitazioni usano il provider SqlClient, la Adapter proprietà è di tipo SqlDataAdapter.

La proprietà s Adapter di TableAdapter ha tre proprietà di tipo SqlCommand usate per rilasciare le istruzioni INSERT, UPDATE e DELETE.

  • InsertCommand
  • UpdateCommand
  • DeleteCommand

Un SqlCommand oggetto è responsabile dell'invio di una query specifica al database e dispone di proprietà come : CommandText, che contiene l'istruzione SQL ad hoc o la stored procedure da eseguire e Parameters, ovvero una raccolta di SqlParameter oggetti . Come illustrato di nuovo nell'esercitazione Creazione di un livello di accesso ai dati , questi oggetti comando possono essere personalizzati tramite la finestra Proprietà.

Oltre alla query principale, TableAdapter può includere un numero variabile di metodi che, quando richiamati, inviano un comando specificato al database. L'oggetto comando della query principale e gli oggetti comando per tutti i metodi aggiuntivi vengono archiviati nella proprietà TableAdapter.CommandCollection

Prendiamo un momento per esaminare il codice generato da ProductsTableAdapter nel Northwind DataSet per queste due proprietà, le loro variabili membro e i metodi di supporto e aiuto.

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

Il codice per le Adapter proprietà e CommandCollection simula attentamente quello della Connection proprietà . Esistono variabili membro che contengono gli oggetti utilizzati dalle proprietà. Le funzioni di accesso alle proprietà Get iniziano controllando se la variabile membro corrispondente è Nothing. In tal caso, viene chiamato un metodo di inizializzazione che crea un'istanza della variabile membro e assegna le proprietà correlate al comando di base.

Passaggio 4: Esposizione delle impostazioni di Command-Level

Idealmente, le informazioni a livello di comando devono rimanere incapsulate all'interno del livello di accesso ai dati. Se queste informazioni devono essere necessarie in altri livelli dell'architettura, tuttavia, possono essere esposte tramite una classe parziale, proprio come con le impostazioni a livello di connessione.

Poiché TableAdapter ha solo una singola Connection proprietà, il codice per l'esposizione delle impostazioni a livello di connessione è piuttosto semplice. È un po' più complicato quando si modificano le impostazioni a livello di comando perché TableAdapter può avere più oggetti comando, ovvero InsertCommand, UpdateCommande DeleteCommand, insieme a un numero variabile di oggetti comando nella CommandCollection proprietà . Quando si aggiornano le impostazioni a livello di comando, queste impostazioni devono essere propagate a tutti gli oggetti comando.

Si supponga, ad esempio, che siano presenti determinate query nell'oggetto TableAdapter che richiedevano molto tempo per l'esecuzione. Quando si usa TableAdapter per eseguire una di queste query, si potrebbe voler aumentare la proprietà dell'oggetto comando CommandTimeout. Questa proprietà specifica il numero di secondi di attesa per l'esecuzione del comando e il valore predefinito è 30.

Per consentire la modifica della CommandTimeout proprietà da parte del BLL, aggiungere il metodo seguente Public all'oggetto ProductsDataTable usando il file di classe parziale creato nel passaggio 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

Questo metodo può essere richiamato dal livello BLL o Presentation per impostare il timeout del comando per tutti i comandi generati dall'istanza di TableAdapter.

Annotazioni

Le Adapter proprietà e CommandCollection sono contrassegnate come Private, ovvero è possibile accedervi solo dal codice all'interno dell'oggetto TableAdapter. A differenza della Connection proprietà, questi modificatori di accesso non sono configurabili. Pertanto, se è necessario esporre le proprietà a livello di comando ad altri livelli nell'architettura, è necessario usare l'approccio parziale della classe descritto in precedenza per fornire un metodo o una Public proprietà che legge o scrive negli Private oggetti comando.

Riassunto

Gli oggetti TableAdapter all'interno di un dataset tipizzato servono per incapsulare i dettagli di accesso ai dati e la complessità. Usando TableAdapters, non è necessario preoccuparsi di scrivere ADO.NET codice per connettersi al database, eseguire un comando o popolare i risultati in una tabella DataTable. È tutto gestito automaticamente per noi.

Tuttavia, potrebbero verificarsi momenti in cui è necessario personalizzare i ADO.NET specifici di basso livello, ad esempio la modifica della stringa di connessione o la connessione predefinita o i valori di timeout dei comandi. TableAdapter ha generato automaticamente le proprietà Connection, Adapter e CommandCollection, ma queste sono Friend o Private per impostazione predefinita. Queste informazioni interne possono essere esposte estendendo TableAdapter usando classi parziali per includere Public metodi o proprietà. In alternativa, è possibile configurare il modificatore di accesso alla proprietà TableAdapter Connection tramite la proprietà TableAdapter ConnectionModifier .

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto a mitchell@4GuysFromRolla.com.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da molti revisori competenti. I revisori principali per questo tutorial erano Burnadette Leigh, Søren Jacob Lauritsen, Teresa Murphy e Hilton Geisenow. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.