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

di Scott Mitchell

Scarica il PDF

TableAdapters all'interno di un dataset tipizzato si occupa automaticamente della connessione al database, dell'emissione di comandi e della compilazione di una tabella dati con i risultati. Tuttavia, in questa esercitazione viene illustrato come accedere alle impostazioni di connessione al database e a livello di comando in TableAdapter.

Introduzione

In tutta la serie di esercitazioni sono stati usati Set di dati tipizzati per implementare gli oggetti business e livello di accesso ai dati dell'architettura a livelli. Come illustrato nella prima esercitazione, i datatable di DataTable di Typed DataSet fungono da repository di dati mentre TableAdapters funge da wrapper per comunicare con il database per recuperare e modificare i dati sottostanti. TableAdapters incapsula la complessità interessata all'uso del database e salva la necessità di scrivere codice per connettersi al database, eseguire un comando o popolare i risultati in una tabella dati.

Tuttavia, quando è necessario scavare nelle profondità dell'oggetto TableAdapter e scrivere codice che funziona direttamente con gli oggetti ADO.NET. Nell'esercitazione Modifiche al database di wrapping in un'esercitazione Sulle transazioni , ad esempio, sono stati aggiunti metodi all'oggetto TableAdapter per iniziare, eseguire il commit e eseguire il rollback delle transazioni ADO.NET. Questi metodi usano un oggetto interno creato SqlTransaction manualmente che è stato assegnato agli oggetti TableAdapter SqlCommand .

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

Uso dei dati tramite ADO.NET

Microsoft .NET Framework contiene una pletora di classi progettate in modo specifico per lavorare con i dati. Queste classi, trovate all'interno dello System.Data spazio dei nomi, vengono definite classi ADO.NET . Alcune delle classi sotto l'ombrello ADO.NET sono associate a un determinato provider di dati. È possibile pensare a un provider di dati come canale di comunicazione che consente alle informazioni di fluire 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, mentre è possibile connettersi a un database microsoft SQL Server usando il provider OleDb, il provider SqlClient è molto più efficiente in quanto è stato progettato e ottimizzato in modo specifico per SQL Server.

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

  1. Stabilire una connessione al database.
  2. Emettere un comando.
  3. Per SELECT le 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 per il database, usare la SqlCommand classe .

Ad eccezione delle modifiche al database di wrapping all'interno di un'esercitazione sulle transazioni , non è necessario scrivere codice di basso livello ADO.NET perché il codice generato automaticamente tableAdapters include le funzionalità necessarie per connettersi al database, eseguire comandi, recuperare dati e popolare tali dati in DataTable. Tuttavia, potrebbero esserci momenti in cui è necessario personalizzare queste impostazioni di basso livello. Nei passaggi successivi si esaminerà come accedere agli oggetti ADO.NET usati internamente da TableAdapters.

Passaggio 1: Esame con la proprietà di connessione

Ogni classe TableAdapter ha una Connection proprietà che specifica le informazioni di connessione del database. Questo tipo di dati e ConnectionString il valore della proprietà sono determinati dalle selezioni effettuate nella procedura guidata Di configurazione TableAdapter. Si ricordi che quando si aggiunge prima una tabellaAdapter a un DataSet tipizzato, questa procedura guidata richiede l'origine del database (vedere la figura 1). L'elenco a discesa in questo primo passaggio include tali database specificati nel file di configurazione e tutti gli altri database nel Connections dati di Esplora server. Se il database da usare non esiste nell'elenco a discesa, è possibile specificare una nuova connessione di database facendo clic sul pulsante Nuova connessione e fornendo 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 full-size)

È possibile esaminare il codice per la proprietà TableAdapter s 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). Nella parte superiore della finestra Visualizzazione classi eseguire il drill-down dello NorthwindTableAdapters spazio dei nomi e selezionare la ProductsTableAdapter classe. Verranno visualizzati i ProductsTableAdapter membri nella metà inferiore della visualizzazione classe, come illustrato nella figura 2. Fare doppio clic sulla proprietà per visualizzarne il Connection codice.

Fare doppio clic sulla proprietà connessione nella visualizzazione classe per visualizzare il codice generato automaticamente

Figura 2: Double-Click la proprietà connection nella visualizzazione classe per visualizzare il codice generato automaticamente

La proprietà TableAdapter e Connection altro codice correlato alla connessione segue:

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 _connection membro è uguale a Nothing. Quando si accede alla proprietà, verifica prima di tutto se la Connection variabile membro è stata creata un'istanza _connection . Se non è presente, il InitConnection metodo viene richiamato, che crea un'istanza _connection e imposta la relativa ConnectionString proprietà sul valore stringa di connessione specificato dalla procedura guidata Di configurazione TableAdapter.

La Connection proprietà può anche essere assegnata a un SqlConnection oggetto. In questo modo, associa il nuovo SqlConnection oggetto 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 possono essere accessibili ad altri livelli nell'architettura dell'applicazione. Tuttavia, potrebbero esserci scenari quando le informazioni a livello di connessione di TableAdapter devono essere accessibili o personalizzabili per una query, un utente o una pagina ASP.NET.

Consente di estendere l'oggetto ProductsTableAdapterNorthwind in DataSet per includere una ConnectionString proprietà che può essere usata dal livello della logica di business per leggere o modificare la stringa di connessione usata dall'oggetto TableAdapter.

Nota

Un 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 di modelli stringa di connessione usati da un'ampia gamma di 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. Prima di tutto, creare 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 e quindi premere la chiave di periodo per visualizzare IntelliSense. Verrà visualizzata la nuova ConnectionString proprietà disponibile in IntelliSense, ovvero è possibile leggere o regolare questo valore a livello di codice dal BLL.

Esposizione dell'intero oggetto connection

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

Aprire DataSetNorthwind, fare clic sull'oggetto ProductsTableAdapter nella Designer e passare alla Finestra Proprietà. Verrà visualizzato il ConnectionModifier set sul relativo valore predefinito, Assembly. Per rendere disponibile la Connection proprietà all'esterno dell'assembly Typed DataSet, modificare la ConnectionModifier proprietà su Public.

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

Figura 4: il Connection livello di accessibilità della proprietà può essere configurato tramite la ConnectionModifier proprietà (fare clic per visualizzare l'immagine a dimensioni complete)

Salvare DataSet e quindi tornare alla ProductsBLL classe. Come prima, passare a uno dei metodi esistenti e digitare Adapter e quindi premere la chiave di periodo 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 TableAdapter è costituito da una query principale che, per impostazione predefinita, include istruzioni , e DELETE generate INSERTUPDATEautomaticamente. Questa query principale di , UPDATEe DELETE le istruzioni vengono implementate nel codice tableAdapter INSERTcome oggetto adattatore dati ADO.NET tramite la Adapter proprietà . Come con la 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à TableAdapter Adapter ha tre proprietà di tipo SqlCommand usate per rilasciare le INSERTistruzioni , UPDATEe DELETE :

  • InsertCommand
  • UpdateCommand
  • DeleteCommand

Un SqlCommand oggetto è responsabile dell'invio di una determinata query 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 di 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

È possibile esaminare il codice generato dall'oggetto ProductsTableAdapterNorthwind In DataSet per queste due proprietà e i relativi metodi helper e variabili membro di supporto:

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 strettamente quello della Connection proprietà. Esistono variabili membro che contengono gli oggetti usati dalle proprietà. Le funzioni di accesso delle 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 ai comandi principali.

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 esporre le impostazioni a livello di connessione è abbastanza semplice. Le cose sono un po'più complicate quando si modificano le impostazioni a livello di comando perché TableAdapter può avere più oggetti comando - un InsertCommandoggetto , UpdateCommande , DeleteCommandinsieme 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 in TableAdapter siano state eseguite alcune query che hanno impiegato molto tempo per l'esecuzione. Quando si usa TableAdapter per eseguire una di queste query, è possibile aumentare la proprietà dell'oggetto CommandTimeoutcomando. Questa proprietà specifica il numero di secondi per attendere l'esecuzione del comando e il valore predefinito è 30.

Per consentire la regolazione della CommandTimeout proprietà da parte del BLL, aggiungere il metodo seguente Public all'uso ProductsDataTable del 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 dei comandi per tutti i problemi dei comandi da tale istanza di TableAdapter.

Nota

Le Adapter proprietà e CommandCollection sono contrassegnate come Private, ovvero possono essere accessibili solo dal codice all'interno di 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 di classe parziale descritto in precedenza per fornire un metodo o una Public proprietà che legge o scrive negli Private oggetti comando.

Riepilogo

I TableAdapter all'interno di un dataset tipizzato servono per incapsulare i dettagli di accesso ai dati e la complessità. L'uso di TableAdapters non deve preoccuparsi di scrivere codice ADO.NET per connettersi al database, emettere un comando o popolare i risultati in una tabella dati. È tutto gestito automaticamente per noi.

Tuttavia, potrebbero verificarsi momenti in cui è necessario personalizzare le specifiche di ADO.NET di basso livello, ad esempio la modifica del stringa di connessione o i valori di timeout predefinito della connessione o del comando. TableAdapter ha proprietà generate Connectionautomaticamente , Adaptere , 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, il modificatore di Connection accesso alla proprietà TableAdapter può essere configurato tramite la proprietà TableAdapter.ConnectionModifier

Programmazione felice!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.

Grazie speciali

Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali per questa esercitazione sono stati Burnadette Leigh, S ren Jacob Lauritsen, Teresa Murphy e Hilton Geisenow. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.