Aggiornamento del TableAdapter per l'uso dei join (VB)

di Scott Mitchell

Scarica il PDF

Quando si usa un database, è comune richiedere i dati distribuiti tra più tabelle. Per recuperare i dati da due tabelle diverse, è possibile usare una sottoquery correlata o un'operazione JOIN. In questa esercitazione vengono confrontate le sottoquerie correlate e la sintassi JOIN prima di esaminare come creare un TableAdapter che include un JOIN nella query principale.

Introduzione

Con i database relazionali i dati con cui si è interessati a lavorare sono spesso distribuiti tra più tabelle. Ad esempio, quando vengono visualizzate informazioni sul prodotto, è probabile che si voglia elencare ogni categoria corrispondente e i nomi dei fornitori. La Products tabella contiene CategoryID e SupplierID valori, ma rispettivamente la categoria effettiva e i nomi dei fornitori sono presenti nelle Categories tabelle e Suppliers .

Per recuperare informazioni da un'altra tabella correlata, è possibile usare sottoquerie correlate o JOINs. Una sottoquery correlata è una query annidata SELECT che fa riferimento alle colonne nella query esterna. Ad esempio, nell'esercitazione Creazione di un livello di accesso ai dati sono stati usati due sottoquerie correlate nella ProductsTableAdapter query principale della query principale per restituire la categoria e i nomi dei fornitori per ogni prodotto. È JOIN un costrutto SQL che unisce righe correlate da due tabelle diverse. È stato usato un JOIN oggetto nell'esercitazione Querying Data with the SqlDataSource Control (Controllo SqlDataSource ) per visualizzare le informazioni sulle categorie insieme a ogni prodotto.

Il motivo per cui si è astenuto dall'uso JOIN di s con TableAdapters è dovuto alle limitazioni della procedura guidata di TableAdapter per generare automaticamente istruzioni corrispondenti INSERT, UPDATEe DELETE . In particolare, se la query principale di TableAdapter contiene qualsiasi JOIN s, TableAdapter non può creare automaticamente le istruzioni SQL ad hoc o le stored procedure per le relative InsertCommandproprietà , UpdateCommande DeleteCommand .

In questa esercitazione verrà brevemente confrontato e confrontato con le sottoquerie correlate e JOIN prima di esplorare come creare un TableAdapter che include JOIN s nella relativa query principale.

Confronto e contrasto di sottoquerie correlate eJOIN s

Tenere presente che la ProductsTableAdapter creazione nella prima esercitazione in Northwind DataSet usa sottoquerie correlate per ripristinare ogni categoria e nome fornitore corrispondente di ogni prodotto. La ProductsTableAdapter query principale è illustrata di seguito.

SELECT ProductID, ProductName, SupplierID, CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = 
            Products.CategoryID) as CategoryName, 
       (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = 
            Products.SupplierID) as SupplierName
FROM Products

Le due sottoquerie (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) correlate, e (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) sono SELECT query che restituiscono un singolo valore per prodotto come colonna aggiuntiva nell'elenco di colonne dell'istruzione esterna SELECT .

In alternativa, è possibile utilizzare un oggetto JOIN per restituire ogni fornitore e nome categoria del prodotto. La query seguente restituisce lo stesso output di quello precedente, ma usa JOIN il posto delle sottoquerie:

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Un JOIN oggetto unisce i record di una tabella con record da un'altra tabella in base a alcuni criteri. Nella query precedente, ad esempio, il LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID indica SQL Server di unire ogni record prodotto con il record di categoria il cui CategoryID valore corrisponde al valore del CategoryID prodotto. Il risultato unito consente di usare i campi categoria corrispondenti per ogni prodotto (ad esempio CategoryName).

Nota

JOIN s viene comunemente usato durante l'esecuzione di query sui dati dai database relazionali. Se non si ha una nuova sintassi o è necessario pennellare un po' sull'utilizzo, è consigliabile usare l'esercitazione JOINdi Join SQL in W3 Schools. Vale anche la pena leggere sono le JOIN sezioni Nozioni fondamentali e Nozioni fondamentali subquery della documentazione online di SQL.

Poiché JOIN le sottoquerie correlate e s possono essere usate per recuperare i dati correlati da altre tabelle, molti sviluppatori hanno lasciato graffiare le loro teste e chiedersi quale approccio usare. Tutti i guru SQL che ho parlato hanno detto approssimativamente la stessa cosa, che non importa davvero prestazioni saggio come SQL Server produrre piani di esecuzione approssimativamente identici. I loro consigli, quindi, è usare la tecnica che voi e il vostro team sono più comodi con. Merita di notare che dopo aver impartito questo consiglio questi esperti esprimono immediatamente la loro preferenza per JOIN le sottoquerie correlate.

Quando si crea un livello di accesso ai dati usando i set di dati tipizzato, gli strumenti funzionano meglio quando si usano sottoquery. In particolare, la procedura guidata di TableAdapter non genererà automaticamente le istruzioni corrispondenti INSERT, UPDATEe DELETE se la query principale contiene qualsiasi JOIN s, ma genererà automaticamente queste istruzioni quando vengono usate sottoquerie correlate.

Per esplorare questo breve problema, creare un dataset tipizzato temporaneo nella ~/App_Code/DAL cartella. Durante la configurazione guidata TableAdapter scegliere di usare istruzioni SQL ad hoc e immettere la query seguente SELECT (vedere la figura 1):

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Screenshot che mostra la finestra Configurazione guidata TableAdaptor con una query immessa che contiene JOINs.

Figura 1: Immettere una query principale contenente JOIN s (fare clic per visualizzare l'immagine a dimensioni complete)

Per impostazione predefinita, TableAdapter creerà INSERTautomaticamente istruzioni , UPDATEe DELETE in base alla query principale. Se si fa clic sul pulsante Avanzate è possibile notare che questa funzionalità è abilitata. Nonostante questa impostazione, TableAdapter non sarà in grado di creare le INSERTistruzioni , UPDATEe DELETE perché la query principale contiene un JOINoggetto .

Screenshot che mostra la finestra Opzioni avanzate con la casella di controllo Genera istruzioni Inserisci, Aggiorna ed Elimina selezionata.

Figura 2: Immettere una query principale contenente JOIN s

Fare clic su Fine per completare la procedura guidata. A questo punto, il Designer di DataSet includerà un singolo TableAdapter con colonne per ognuno dei campi restituiti nell'elenco SELECT di colonne della query. Include l'oggetto e , SupplierNamecome illustrato nella CategoryName figura 3.

DataTable include una colonna per ogni campo restituito nell'elenco di colonne

Figura 3: DataTable include una colonna per ogni campo restituito nell'elenco colonne

Sebbene DataTable disponga delle colonne appropriate, TableAdapter manca di valori per le relative InsertCommandproprietà , UpdateCommande DeleteCommand . Per confermare questa operazione, fare clic su TableAdapter nel Designer e quindi passare alla Finestra Proprietà. Verrà visualizzato che le InsertCommandproprietà , UpdateCommande DeleteCommand sono impostate su (Nessuno).

Le proprietà InsertCommand, UpdateCommand e DeleteCommand sono impostate su (Nessuna)

Figura 4: Le InsertCommandproprietà , UpdateCommande DeleteCommand sono impostate su (Nessuna) (Fare clic per visualizzare l'immagine full-size)

Per risolvere questo problema, è possibile specificare manualmente le istruzioni e i parametri SQL per le proprietà , UpdateCommande DeleteCommand tramite la InsertCommandFinestra Proprietà. In alternativa, è possibile iniziare configurando la query principale di TableAdapter per non includere alcuna JOIN s. In questo modo verranno generate automaticamente le INSERTistruzioni , UPDATEe DELETE . Dopo aver completato la procedura guidata, è possibile aggiornare manualmente l'oggetto TableAdapter dal SelectCommand Finestra Proprietà in modo che includa la JOIN sintassi.

Sebbene questo approccio funzioni, è molto fragile quando si usano query SQL ad hoc perché ogni volta che la query principale di TableAdapter viene riconfigurata tramite la procedura guidata, vengono ricreate le istruzioni , UPDATEe DELETE generate INSERTautomaticamente. Ciò significa che tutte le personalizzazioni apportate in seguito verranno perse se si fa clic con il pulsante destro del mouse su TableAdapter, scegliere Configura dal menu di scelta rapida e completare nuovamente la procedura guidata.

La fragilità delle istruzioni , e UPDATEDELETE generate INSERTautomaticamente di TableAdapter è, fortunatamente, limitata alle istruzioni SQL ad hoc. Se tableAdapter usa stored procedure, è possibile personalizzare le SelectCommandstored procedure , UpdateCommandInsertCommand, o o DeleteCommand e eseguire nuovamente la procedura guidata Di configurazione TableAdapter senza dover temere che le stored procedure vengano modificate.

Nei diversi passaggi successivi verrà creato un TableAdapter che, inizialmente, usa una query principale che omette qualsiasi JOIN s in modo che le stored procedure di inserimento, aggiornamento ed eliminazione corrispondenti vengano generate automaticamente. Verrà quindi aggiornato in SelectCommand modo che usi un JOIN oggetto che restituisce colonne aggiuntive da tabelle correlate. Infine, verrà creata una classe Business Logic Layer corrispondente e verrà illustrata l'uso di TableAdapter in una pagina Web ASP.NET.

Passaggio 1: Creazione di TableAdapter usando una query principale semplificata

Per questa esercitazione verrà aggiunto un oggetto TableAdapter e dataTable fortemente tipizzato per la Employees tabella in NorthwindWithSprocs DataSet. La Employees tabella contiene un ReportsTo campo che ha specificato il EmployeeID responsabile del dipendente. Ad esempio, il dipendente Anne Dodsworth ha un ReportTo valore pari a 5, che è quello EmployeeID di Steven Buchanan. Di conseguenza, Anne riferisce a Steven, il suo manager. Oltre a segnalare il valore di ReportsTo ogni dipendente, potremmo anche voler recuperare il nome del proprio manager. Questa operazione può essere eseguita usando un JOINoggetto . Tuttavia, l'uso di un JOIN oggetto durante la creazione iniziale di TableAdapter impedisce alla procedura guidata di generare automaticamente le funzionalità di inserimento, aggiornamento ed eliminazione corrispondenti. Si inizierà quindi creando un TableAdapter la cui query principale non contiene alcun JOIN s. Nel passaggio 2 verrà quindi aggiornata la stored procedure principale della query per recuperare il nome del gestore tramite un JOINoggetto .

Iniziare aprendo DataSet NorthwindWithSprocs nella ~/App_Code/DAL cartella. Fare clic con il pulsante destro del mouse sulla Designer, selezionare l'opzione Aggiungi dal menu di scelta rapida e scegliere la voce di menu TableAdapter. Verrà avviata la procedura guidata Di configurazione TableAdapter. Come illustrato nella figura 5, creare nuove stored procedure e fare clic su Avanti. Per un aggiornamento sulla creazione di nuove stored procedure dalla procedura guidata tableAdapter, consultare l'esercitazione Creazione di nuove stored procedure per l'esercitazione TableAdapters di DataSet tipizzato .

Selezionare l'opzione Crea nuove stored procedure

Figura 5: Selezionare l'opzione Crea nuove stored procedure (Fare clic per visualizzare l'immagine full-size)

Usare l'istruzione seguente SELECT per la query principale di TableAdapter:

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

Poiché questa query non include alcuna JOIN query, la procedura guidata TableAdapter creerà automaticamente stored procedure con istruzioni , UPDATEe DELETE corrispondentiINSERT, nonché una stored procedure per l'esecuzione della query principale.

Il passaggio seguente consente di assegnare un nome alle stored procedure di TableAdapter. Usare i nomi Employees_Select, Employees_Insert, Employees_Update, e Employees_Delete, come illustrato nella figura 6.

Assegnare un nome alle stored procedure di TableAdapter

Figura 6: Assegnare un nome alle stored procedure di TableAdapter (fare clic per visualizzare l'immagine full-size)

Il passaggio finale richiede di assegnare un nome ai metodi TableAdapter. Usare Fill e GetEmployees come nomi dei metodi. Assicurarsi anche di lasciare selezionata la casella di controllo Crea metodi per inviare gli aggiornamenti direttamente al database (GenerateDBDirectMethods).

Assegnare un nome ai metodi TableAdapter Fill e GetEmployees

Figura 7: Assegnare un nome ai metodi Fill di TableAdapter e GetEmployees (fare clic per visualizzare l'immagine a dimensioni complete)

Dopo aver completato la procedura guidata, esaminare le stored procedure nel database. Verranno visualizzate quattro nuove: Employees_Select, Employees_Insert, Employees_Updatee Employees_Delete. Esaminare quindi e EmployeesDataTableEmployeesTableAdapter appena creato. DataTable contiene una colonna per ogni campo restituito dalla query principale. Fare clic su TableAdapter e quindi passare alla Finestra Proprietà. Si noterà che le InsertCommandproprietà , UpdateCommande DeleteCommand sono configurate correttamente per chiamare le stored procedure corrispondenti.

TableAdapter include funzionalità inserimento, aggiornamento ed eliminazione

Figura 8: TableAdapter include funzionalità inserimento, aggiornamento ed eliminazione (fare clic per visualizzare l'immagine full-size)

Con le stored procedure di inserimento, aggiornamento ed eliminazione create automaticamente e le InsertCommandproprietà , UpdateCommande DeleteCommand configurate correttamente, è possibile personalizzare la SelectCommand stored procedure per restituire informazioni aggiuntive su ogni responsabile del dipendente. In particolare, è necessario aggiornare la Employees_Select stored procedure per usare un JOIN oggetto e restituire i valori e degli s FirstName e LastName del manager. Dopo l'aggiornamento della stored procedure, sarà necessario aggiornare DataTable in modo che includa queste colonne aggiuntive. Verranno affrontate queste due attività nei passaggi 2 e 3.

Passaggio 2: Personalizzazione della stored procedure per includere unJOIN

Per iniziare, passare a Esplora server, eseguire il drill-down nella cartella Stored Procedure del database Northwind e aprire la Employees_Select stored procedure. Se questa stored procedure non viene visualizzata, fare clic con il pulsante destro del mouse sulla cartella Stored Procedure e scegliere Aggiorna. Aggiornare la stored procedure in modo che usi un LEFT JOIN oggetto per restituire il nome e il cognome del gestore:

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

Dopo aver aggiornato l'istruzione SELECT , salvare le modifiche passando al menu File e scegliendo Salva Employees_Select. In alternativa, è possibile fare clic sull'icona Salva sulla barra degli strumenti o premere CTRL+S. Dopo aver salvato le modifiche, fare clic con il pulsante destro del mouse sulla Employees_Select stored procedure in Esplora server e scegliere Esegui. Verrà eseguita la stored procedure e verranno visualizzati i risultati nella finestra Output (vedere la figura 9).

I risultati delle stored procedure vengono visualizzati nella finestra di output

Figura 9: i risultati delle stored procedure vengono visualizzati nella finestra di output (fare clic per visualizzare l'immagine full-size)

Passaggio 3: Aggiornamento delle colonne di DataTable

A questo punto, la Employees_Select stored procedure restituisce ManagerFirstName e ManagerLastName i valori, ma manca EmployeesDataTable queste colonne. Queste colonne mancanti possono essere aggiunte a DataTable in uno dei due modi seguenti:

  • Manualmente: fare clic con il pulsante destro del mouse su DataTable nella Designer DataSet e scegliere Colonna dal menu Aggiungi. È quindi possibile assegnare un nome alla colonna e impostarne le proprietà di conseguenza.
  • Automaticamente : la configurazione guidata TableAdapter aggiornerà le colonne di DataTable per riflettere i campi restituiti dalla SelectCommand stored procedure. Quando si usano istruzioni SQL ad hoc, la procedura guidata rimuoverà anche le InsertCommandproprietà , UpdateCommande DeleteCommand perché ora SelectCommand contiene un JOINoggetto . Tuttavia, quando si usano stored procedure, queste proprietà dei comandi rimangono intatte.

Sono state esaminate manualmente l'aggiunta manuale di colonne dataTable nelle esercitazioni precedenti, tra cui Master/Detail Using a Bulleted List of Master Records with a Details DataList and Uploading Files(Elenco dati dettagli e caricamento di file) e verrà esaminato di nuovo questo processo in modo più dettagliato nell'esercitazione successiva. Per questa esercitazione, tuttavia, consente di usare l'approccio automatico tramite la procedura guidata Di configurazione TableAdapter.

Iniziare facendo clic con il EmployeesTableAdapter pulsante destro del mouse su e selezionando Configura dal menu di scelta rapida. Viene visualizzata la procedura guidata Di configurazione TableAdapter, che elenca le stored procedure usate per la selezione, l'inserimento, l'aggiornamento e l'eliminazione, insieme ai relativi valori e parametri restituiti (se presente). La figura 10 mostra questa procedura guidata. Qui è possibile notare che la Employees_Select stored procedure restituisce ora i ManagerFirstName campi e ManagerLastName .

La procedura guidata mostra l'elenco di colonne aggiornate per la stored procedure di Employees_Select

Figura 10: La procedura guidata mostra l'elenco di colonne aggiornate per la Employees_Select stored procedure (fare clic per visualizzare l'immagine full-size)

Completare la procedura guidata facendo clic su Fine. Al ritorno alla Designer dataset, EmployeesDataTable sono incluse due colonne aggiuntive: ManagerFirstName e ManagerLastName.

EmployeesDataTable contiene due nuove colonne

Figura 11: Contiene EmployeesDataTable due nuove colonne (fare clic per visualizzare l'immagine full-size)

Per illustrare che la stored procedure aggiornata è effettiva e che le funzionalità di inserimento Employees_Select , aggiornamento ed eliminazione di TableAdapter sono ancora funzionali, consentono di creare una pagina Web che consente agli utenti di visualizzare ed eliminare i dipendenti. Prima di creare una pagina di questo tipo, è tuttavia necessario creare prima una nuova classe nel livello di logica di business per lavorare con i dipendenti da NorthwindWithSprocs DataSet. Nel passaggio 4 verrà creata una EmployeesBLLWithSprocs classe. Nel passaggio 5 verrà usata questa classe da una pagina ASP.NET.

Passaggio 4: Implementazione del livello di logica di business

Creare un nuovo file di classe nella ~/App_Code/BLL cartella denominata EmployeesBLLWithSprocs.vb. Questa classe simula la semantica della classe esistente EmployeesBLL , solo questa nuova fornisce meno metodi e usa DataSet NorthwindWithSprocs (anziché Northwind DataSet). Aggiungere il codice seguente alla classe EmployeesBLLWithSprocs .

Imports NorthwindWithSprocsTableAdapters
<System.ComponentModel.DataObject()> _
Public Class EmployeesBLLWithSprocs
    Private _employeesAdapter As EmployeesTableAdapter = Nothing
    Protected ReadOnly Property Adapter() As EmployeesTableAdapter
        Get
            If _employeesAdapter Is Nothing Then
                _employeesAdapter = New EmployeesTableAdapter()
            End If
            Return _employeesAdapter
        End Get
    End Property
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Function GetEmployees() As NorthwindWithSprocs.EmployeesDataTable
        Return Adapter.GetEmployees()
    End Function
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Delete, True)> _
    Public Function DeleteEmployee(ByVal employeeID As Integer) As Boolean
        Dim rowsAffected = Adapter.Delete(employeeID)
        'Return true if precisely one row was deleted, otherwise false
        Return rowsAffected = 1
    End Function
End Class

La EmployeesBLLWithSprocs proprietà della Adapter classe restituisce un'istanza NorthwindWithSprocs di DataSet s EmployeesTableAdapter. Questa operazione viene usata dai metodi e DeleteEmployee della GetEmployees classe. Il GetEmployees metodo chiama il metodo corrispondenteGetEmployees, che richiama la EmployeesTableAdapterEmployees_Select stored procedure e popola i risultati in un oggetto EmployeeDataTable. Il DeleteEmployee metodo chiama in modo analogo il EmployeesTableAdapter metodo s Delete , che richiama la Employees_Delete stored procedure.

Passaggio 5: Uso dei dati nel livello presentazione

Con il completamento della EmployeesBLLWithSprocs classe, è possibile lavorare con i dati dei dipendenti tramite una pagina di ASP.NET. Aprire la JOINs.aspx pagina nella AdvancedDAL cartella e trascinare gridView dalla casella degli strumenti nella Designer, impostandone la ID proprietà su Employees. Successivamente, dallo smart tag gridView, associare la griglia a un nuovo controllo ObjectDataSource denominato EmployeesDataSource.

Configurare ObjectDataSource per usare la EmployeesBLLWithSprocs classe e, dalle schede SELECT e DELETE, assicurarsi che i GetEmployees metodi e DeleteEmployee siano selezionati dagli elenchi a discesa. Fare clic su Fine per completare la configurazione di ObjectDataSource.

Configurare ObjectDataSource per usare la classe EmployeesBLLWithSprocs

Figura 12: Configurare ObjectDataSource per usare la classe (fare clic per visualizzare l'immagineEmployeesBLLWithSprocs full-size)

Usare ObjectDataSource e i metodi GetEmployees e DeleteEmployee

Figura 13: Disporre di ObjectDataSource Usare i GetEmployees metodi e DeleteEmployee (Fare clic per visualizzare l'immagine full-size)

Visual Studio aggiungerà un oggetto BoundField a GridView per ognuna delle EmployeesDataTable colonne di . Rimuovere tutti questi BoundField, ad eccezione Titledi , LastNameFirstNameManagerFirstNamee ManagerLastName rinominare rispettivamente le proprietà per gli HeaderText ultimi quattro Campi delimitatori in Cognome, Nome, Nome di gestione e Cognome di Manager.

Per consentire agli utenti di eliminare i dipendenti da questa pagina, è necessario eseguire due operazioni. In primo luogo, indicare a GridView di fornire funzionalità di eliminazione controllando l'opzione Abilita eliminazione dal relativo smart tag. In secondo luogo, modificare la proprietà ObjectDataSource s OldValuesParameterFormatString dal valore impostato dalla procedura guidata ObjectDataSource () al relativo valore predefinito (original_{0}{0}). Dopo aver apportato queste modifiche, il markup dichiarativo gridView e ObjectDataSource deve essere simile al seguente:

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Testare la pagina visitandola tramite un browser. Come illustrato nella figura 14, la pagina elenca ogni dipendente e il nome del suo responsabile (presupponendo che ne abbiano uno).

Join nella stored procedure di Employees_Select restituisce il nome di Manager

Figura 14: Nella JOINEmployees_Select stored procedure restituisce il nome di Manager (fare clic per visualizzare l'immagine full-size)

Facendo clic sul pulsante Elimina viene avviato il flusso di lavoro di eliminazione, che culmina nell'esecuzione della Employees_Delete stored procedure. Tuttavia, l'istruzione tentata DELETE nella stored procedure ha esito negativo a causa di una violazione del vincolo di chiave esterna (vedere la figura 15). In particolare, ogni dipendente ha uno o più record nella Orders tabella, causando l'esito negativo dell'eliminazione.

L'eliminazione di un dipendente con ordini corrispondenti comporta una violazione del vincolo di chiave esterna

Figura 15: Eliminazione di un dipendente con ordini corrispondenti genera una violazione del vincolo di chiave esterna (fare clic per visualizzare l'immagine full-size)

Per consentire l'eliminazione di un dipendente, è possibile:

Lascio questo come esercizio per il lettore.

Riepilogo

Quando si usano i database relazionali, è comune che le query estraino i dati da più tabelle correlate. Le sottoquerie correlate e JOIN s forniscono due tecniche diverse per l'accesso ai dati da tabelle correlate in una query. Nelle esercitazioni precedenti è stato usato più comunemente di sottoquerie correlate perché TableAdapter non può generare INSERTautomaticamente , UPDATEe DELETE istruzioni per le query che coinvolgono JOIN s. Anche se questi valori possono essere forniti manualmente, quando si usano istruzioni SQL ad hoc, le eventuali personalizzazioni verranno sovrascritte al termine della procedura guidata Di configurazione TableAdapter.

Fortunatamente, TableAdapters creato usando stored procedure non soffrono della stessa brittleness di quelle create usando istruzioni SQL ad hoc. Pertanto, è possibile creare un TableAdapter la cui query principale usa un JOIN oggetto quando si usano stored procedure. In questa esercitazione è stato illustrato come creare un oggetto TableAdapter. È stata avviata l'uso di una JOINquery -less SELECT per la query principale di TableAdapter in modo che le stored procedure di inserimento, aggiornamento ed eliminazione corrispondenti vengano create automaticamente. Con il completamento della configurazione iniziale di TableAdapter, è stata aumentata la SelectCommand stored procedure per usare una JOIN procedura guidata di configurazione TableAdapter per aggiornare le EmployeesDataTable colonne di s.

Eseguire nuovamente la Configurazione guidata TableAdapter aggiorna automaticamente le EmployeesDataTable colonne per riflettere i campi dati restituiti dalla Employees_Select stored procedure. In alternativa, è possibile aggiungere manualmente queste colonne a DataTable. Verranno esaminate manualmente l'aggiunta di colonne alla tabella dati nell'esercitazione successiva.

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 Hilton Geisenow, David Suru e Teresa Murphy. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.