Aggiornamento del TableAdapter per l'uso dei join (C#)
Quando si usa un database, è comune richiedere dati distribuiti tra più tabelle. Per recuperare dati da due tabelle diverse, è possibile usare una sottoquery correlata o un'operazione JOIN. In questa esercitazione vengono confrontate le sottoquery 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 sono spesso distribuiti in più tabelle. Ad esempio, quando vengono visualizzate informazioni sul prodotto, è probabile che si voglia elencare ogni prodotto corrispondente categoria e nomi dei fornitori. La Products
tabella ha CategoryID
valori e SupplierID
, ma i nomi di categoria e fornitori effettivi si trovano rispettivamente nelle Categories
tabelle e Suppliers
.
Per recuperare informazioni da un'altra tabella correlata, è possibile usare sottoquery correlate o JOIN
s. Una sottoquery correlata è una query nidificata SELECT
che fa riferimento a colonne nella query esterna. Ad esempio, nell'esercitazione Creazione di un livello di accesso ai dati sono stati usati due sottoquery 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 Esecuzione di query sui dati con il controllo SqlDataSource per visualizzare le informazioni sulle categorie insieme a ogni prodotto.
Il motivo per cui si è astenuto dall'uso JOIN
di s con gli oggetti TableAdapter è dovuto alle limitazioni della procedura guidata di TableAdapter per generare automaticamente istruzioni , UPDATE
e DELETE
corrispondentiINSERT
. In particolare, se la query principale di TableAdapter contiene oggetti JOIN
, TableAdapter non può creare automaticamente le istruzioni SQL ad hoc o le stored procedure per InsertCommand
le relative proprietà , UpdateCommand
e DeleteCommand
.
In questa esercitazione verranno confrontate brevemente e contrastate sottoquery correlate e JOIN
s prima di esplorare come creare un TableAdapter che include JOIN
s nella query principale.
Confronto e contrasto di sottoquery eJOIN
s correlate
Tenere presente che l'oggetto ProductsTableAdapter
creato nella prima esercitazione in Northwind
DataSet usa sottoquery correlate per riportare ogni prodotto corrispondente categoria e nome fornitore. 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 sottoquery correlate, (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID)
e , sono SELECT
query che restituiscono un singolo valore per prodotto come colonna aggiuntiva nell'elenco di colonne dell'istruzione esterna SELECT
(SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID)
.
In alternativa, è possibile utilizzare un oggetto JOIN
per restituire ogni fornitore e nome di categoria del prodotto. La query seguente restituisce lo stesso output di quello precedente, ma usa JOIN
s al posto delle sottoquery:
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 i record di un'altra tabella in base ad alcuni criteri. Nella query precedente, ad esempio, LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID
indica SQL Server di unire ogni record di prodotto con il record di categoria il cui CategoryID
valore corrisponde al valore del CategoryID
prodotto. Il risultato unito consente di usare i campi di 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 più a che fare con la JOIN
sintassi o se è necessario spolverare un po' sull'utilizzo, è consigliabile usare l'esercitazione per l'aggiunta a SQL in W3 Schools. Vale anche la pena leggere le JOIN
sezioni Nozioni fondamentali e Nozioni fondamentali della sottoquery della documentazione online di SQL.
Poiché JOIN
le sottoquery s e correlate possono essere usate entrambe per recuperare i dati correlati da altre tabelle, molti sviluppatori si mettono a graffiare le teste e chiedersi quale approccio usare. Tutti i guru SQL che ho parlato hanno detto approssimativamente la stessa cosa, che non importa davvero le prestazioni, come SQL Server produrrà piani di esecuzione approssimativamente identici. Il loro consiglio, quindi, è quello di usare la tecnica con cui l'utente e il team sono più comodi. Merita di notare che, dopo aver impartito questo consiglio, questi esperti esprimono immediatamente la loro preferenza per JOIN
le sottoquery correlate.
Quando si compila un livello di accesso ai dati usando set di dati tipiti, gli strumenti funzionano meglio quando si usano sottoquery. In particolare, la procedura guidata di TableAdapter non genererà automaticamente istruzioni , UPDATE
e DELETE
corrispondenti INSERT
se la query principale contiene sJOIN
, ma genererà automaticamente queste istruzioni quando vengono usate sottoquery correlate.
Per esplorare questo 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
Figura 1: Immettere una query principale che contiene JOIN
(fare clic per visualizzare l'immagine a dimensione intera)
Per impostazione predefinita, TableAdapter creerà INSERT
automaticamente istruzioni , UPDATE
e DELETE
in base alla query principale. Se si fa clic sul pulsante Avanzate, si noterà che questa funzionalità è abilitata. Nonostante questa impostazione, TableAdapter non sarà in grado di creare le INSERT
istruzioni , UPDATE
e DELETE
perché la query principale contiene un oggetto JOIN
.
Figura 2: Immettere una query principale che contiene JOIN
s
Fare clic su Fine per completare la procedura guidata. A questo punto l'Designer di DataSet includerà un singolo Oggetto TableAdapter con una tabella DataTable con colonne per ognuno dei campi restituiti nell'elenco SELECT
di colonne della query. Sono inclusi e CategoryName
SupplierName
, come illustrato nella figura 3.
Figura 3: DataTable include una colonna per ogni campo restituito nell'elenco colonne
Mentre DataTable include le colonne appropriate, TableAdapter non dispone di valori per InsertCommand
le relative proprietà , UpdateCommand
e DeleteCommand
. Per confermarlo, fare clic su TableAdapter nel Designer e quindi passare alla Finestra Proprietà. Si noterà che le InsertCommand
proprietà , UpdateCommand
e DeleteCommand
sono impostate su (Nessuno).
Figura 4: Le InsertCommand
proprietà , UpdateCommand
e DeleteCommand
sono impostate su (Nessuna) (Fare clic per visualizzare l'immagine a dimensione intera)
Per risolvere questo problema, è possibile fornire manualmente le istruzioni SQL e i parametri per le InsertCommand
proprietà , UpdateCommand
e DeleteCommand
tramite il Finestra Proprietà. In alternativa, è possibile iniziare configurando la query principale dell'oggetto TableAdapter in modo da non includere elementi JOIN
. In questo modo le INSERT
istruzioni , UPDATE
e DELETE
verranno generate automaticamente. Dopo aver completato la procedura guidata, è possibile aggiornare manualmente l'oggetto TableAdapter dal SelectCommand
Finestra Proprietà in modo che includa la JOIN
sintassi.
Anche se questo approccio funziona, è molto fragile quando si usano query SQL ad hoc perché ogni volta che la query principale di TableAdapter viene riconfigurata tramite la procedura guidata, le istruzioni , UPDATE
e DELETE
generate INSERT
automaticamente vengono ricreate. Ciò significa che tutte le personalizzazioni apportate in un secondo momento andrebbero perse se si fa clic con il pulsante destro del mouse su TableAdapter, si sceglie Configura dal menu di scelta rapida e si completa nuovamente la procedura guidata.
La fragilità delle istruzioni , UPDATE
e DELETE
generate INSERT
automaticamente di TableAdapter è, fortunatamente, limitata alle istruzioni SQL ad hoc. Se tableAdapter usa stored procedure, è possibile personalizzare le SelectCommand
stored procedure , InsertCommand
, UpdateCommand
o DeleteCommand
ed eseguire di nuovo la Configurazione guidata TableAdapter senza dover temere che le stored procedure vengano modificate.
Nei 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 Livello logica di business corrispondente e verrà illustrato l'uso di TableAdapter in una pagina Web ASP.NET.
Passaggio 1: Creazione dell'oggetto TableAdapter tramite una query principale semplificata
Per questa esercitazione si aggiungeranno un oggetto TableAdapter e dataTable fortemente tipizzato per la Employees
tabella in NorthwindWithSprocs
DataSet. La Employees
tabella contiene un ReportsTo
campo che ha specificato l'oggetto EmployeeID
del responsabile del dipendente. Ad esempio, il dipendente Anne Dodsworth ha un ReportTo
valore pari a 5, ovvero quello EmployeeID
di Steven Buchanan. Di conseguenza, Anne riferisce a Steven, il suo manager. Oltre a segnalare il valore di ReportsTo
ogni dipendente, è anche possibile recuperare il nome del responsabile. Questa operazione può essere eseguita usando un oggetto JOIN
. Tuttavia, l'uso di un oggetto JOIN
quando si crea inizialmente 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 elementi JOIN
. Quindi, nel passaggio 2, si aggiornerà la stored procedure di query principale per recuperare il nome del gestore tramite un .JOIN
Per iniziare, aprire l'oggetto NorthwindWithSprocs
DataSet nella ~/App_Code/DAL
cartella . Fare clic con il pulsante destro del mouse sulla Designer, scegliere l'opzione Aggiungi dal menu di scelta rapida e scegliere la voce di menu TableAdapter. Verrà avviata la Configurazione guidata TableAdapter. Come illustrato nella figura 5, creare nuove stored procedure nella procedura guidata e fare clic su Avanti. Per un aggiornamento sulla creazione di nuove stored procedure dalla creazione guidata di TableAdapter, vedere l'esercitazione Creazione di nuove stored procedure per l'esercitazione TableAdapters di DataSet tipizzato .
Figura 5: Selezionare l'opzione Crea nuove stored procedure (fare clic per visualizzare l'immagine a dimensione intera)
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 elementiJOIN
, la Creazione guidata TableAdapter creerà automaticamente stored procedure con istruzioni , UPDATE
e DELETE
corrispondentiINSERT
, nonché una stored procedure per l'esecuzione della query principale.
Il passaggio seguente consente di denominare le stored procedure di TableAdapter. Usare i nomi Employees_Select
, Employees_Insert
, Employees_Update
e Employees_Delete
, come illustrato nella figura 6.
Figura 6: Assegnare un nome alle stored procedure di TableAdapter (fare clic per visualizzare l'immagine a dimensione intera)
Il passaggio finale richiede di denominare i metodi di TableAdapter. Usare Fill
e GetEmployees
come nomi di metodo. Assicurarsi anche di lasciare selezionata la casella di controllo Crea metodi per inviare gli aggiornamenti direttamente al database (GenerateDBDirectMethods).
Figura 7: Denominare i metodi Fill
di TableAdapter e GetEmployees
(fare clic per visualizzare l'immagine a dimensione intera)
Al termine della procedura guidata, esaminare le stored procedure nel database. Dovrebbero essere visualizzati quattro nuovi: Employees_Select
, Employees_Insert
, Employees_Update
e Employees_Delete
. Esaminare quindi e EmployeesDataTable
EmployeesTableAdapter
appena creato. La tabella 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 InsertCommand
proprietà , UpdateCommand
e DeleteCommand
sono configurate correttamente per chiamare le stored procedure corrispondenti.
Figura 8: TableAdapter include funzionalità di inserimento, aggiornamento ed eliminazione (fare clic per visualizzare l'immagine a dimensione intera)
Con le stored procedure di inserimento, aggiornamento ed eliminazione create automaticamente e le InsertCommand
proprietà , UpdateCommand
e 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 e JOIN
restituire i valori e LastName
del FirstName
gestore. Dopo aver aggiornato la stored procedure, sarà necessario aggiornare DataTable in modo che includa queste colonne aggiuntive. Queste due attività verranno affrontate 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 manager:
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 Employees_Select
mouse sulla 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).
Figura 9: I risultati delle stored procedure vengono visualizzati nella finestra di output (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Aggiornamento delle colonne di DataTable
A questo punto, la Employees_Select
stored procedure restituisce ManagerFirstName
i valori e ManagerLastName
, 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 nel Designer DataSet e scegliere Colonna dal menu Aggiungi. È quindi possibile denominare la colonna e impostarne le proprietà di conseguenza.
- Automaticamente : la Configurazione guidata TableAdapter aggiornerà le colonne di DataTable in modo da riflettere i campi restituiti dalla
SelectCommand
stored procedure. Quando si usano istruzioni SQL ad hoc, la procedura guidata rimuoverà anche leInsertCommand
proprietà ,UpdateCommand
eDeleteCommand
poiché oraSelectCommand
contiene un oggettoJOIN
. Tuttavia, quando si usano stored procedure, queste proprietà del comando rimangono intatte.
È stata esaminata 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 puntato di record master con un oggetto Details DataList e caricamento di file) e questo processo verrà esaminato di nuovo in modo più dettagliato nell'esercitazione successiva. Per questa esercitazione, tuttavia, è possibile usare l'approccio automatico tramite la Configurazione guidata TableAdapter.
Per iniziare, fare clic con il pulsante destro del EmployeesTableAdapter
mouse su e scegliere Configura dal menu di scelta rapida. Verrà visualizzata la Configurazione guidata TableAdapter, che elenca le stored procedure usate per la selezione, l'inserimento, l'aggiornamento e l'eliminazione, insieme ai valori restituiti e ai parametri (se presenti). La figura 10 mostra questa procedura guidata. Qui è possibile osservare che la Employees_Select
stored procedure restituisce ora i ManagerFirstName
campi e ManagerLastName
.
Figura 10: La procedura guidata mostra l'elenco di colonne aggiornato per la Employees_Select
stored procedure (fare clic per visualizzare l'immagine a dimensione intera)
Completare la procedura guidata facendo clic su Fine. Al ritorno al Designer DataSet, include EmployeesDataTable
due colonne aggiuntive: ManagerFirstName
e ManagerLastName
.
Figura 11: EmployeesDataTable
Contiene due nuove colonne (fare clic per visualizzare l'immagine a dimensione intera)
Per illustrare che la stored procedure aggiornata Employees_Select
è attiva e che le funzionalità di inserimento, aggiornamento ed eliminazione di TableAdapter sono ancora funzionanti, è possibile 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 una nuova classe nel livello della logica di business per lavorare con i dipendenti di NorthwindWithSprocs
DataSet. Nel passaggio 4 verrà creata una EmployeesBLLWithSprocs
classe. Nel passaggio 5 questa classe verrà usata da una pagina ASP.NET.
Passaggio 4: Implementazione del livello della logica di business
Creare un nuovo file di classe nella ~/App_Code/BLL
cartella denominata EmployeesBLLWithSprocs.cs
. Questa classe simula la semantica della classe esistente EmployeesBLL
, solo questa nuova fornisce un minor numero di metodi e usa l'oggetto NorthwindWithSprocs
DataSet anziché l'oggetto Northwind
DataSet. Aggiungere il codice seguente alla classe EmployeesBLLWithSprocs
.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class EmployeesBLLWithSprocs
{
private EmployeesTableAdapter _employeesAdapter = null;
protected EmployeesTableAdapter Adapter
{
get
{
if (_employeesAdapter == null)
_employeesAdapter = new EmployeesTableAdapter();
return _employeesAdapter;
}
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, true)]
public NorthwindWithSprocs.EmployeesDataTable GetEmployees()
{
return Adapter.GetEmployees();
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteEmployee(int employeeID)
{
int rowsAffected = Adapter.Delete(employeeID);
// Return true if precisely one row was deleted, otherwise false
return rowsAffected == 1;
}
}
La EmployeesBLLWithSprocs
proprietà della Adapter
classe restituisce un'istanza dell'oggetto NorthwindWithSprocs
DataSet s EmployeesTableAdapter
. Viene usato dai metodi e DeleteEmployee
della classe GetEmployees
. Il GetEmployees
metodo chiama il EmployeesTableAdapter
metodo corrispondente GetEmployees
, che richiama la Employees_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: Utilizzo dei dati nel livello presentazione
Al termine 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 di GridView associare la griglia a un nuovo controllo ObjectDataSource denominato EmployeesDataSource
.
Configurare ObjectDataSource per l'uso della 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.
Figura 12: Configurare ObjectDataSource per l'uso della classe (fare clic per visualizzare l'immagineEmployeesBLLWithSprocs
a dimensione intera)
Figura 13: Usare ObjectDataSource metodi GetEmployees
e DeleteEmployee
(fare clic per visualizzare l'immagine a dimensione intera)
Visual Studio aggiungerà un BoundField a GridView per ognuna delle EmployeesDataTable
colonne. Rimuovere tutti questi BoundFields ad eccezione Title
di , LastName
, FirstName
, ManagerFirstName
e e ManagerLastName
rinominare le proprietà per gli HeaderText
ultimi quattro BoundFields in Cognome, Nome, Nome, Nome e Cognome del Manager rispettivamente.
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 selezionando l'opzione Abilita eliminazione dallo smart tag. In secondo luogo, modificare la proprietà ObjectDataSource s OldValuesParameterFormatString
dal valore impostato dalla procedura guidata ObjectDataSource () al valore predefinito (original_{0}
{0}
). Dopo aver apportato queste modifiche, il markup dichiarativo di GridView e ObjectDataSource dovrebbe 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 manager (presupponendo che ne abbiano uno).
Figura 14: l'oggetto JOIN
nella Employees_Select
stored procedure restituisce il nome del manager (fare clic per visualizzare l'immagine a dimensione intera)
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.
Figura 15: Eliminazione di un dipendente con ordini corrispondenti genera una violazione del vincolo di chiave esterna (fare clic per visualizzare l'immagine a dimensione intera)
Per consentire l'eliminazione di un dipendente, è possibile:
- Aggiornare il vincolo di chiave esterna per eliminare a catena,
- Eliminare manualmente i record dalla
Orders
tabella per i dipendenti da eliminare o - Aggiornare la
Employees_Delete
stored procedure per eliminare prima di tutto i record correlati dallaOrders
tabella prima di eliminare ilEmployees
record. Questa tecnica è stata illustrata nell'esercitazione Uso di stored procedure esistenti per l'esercitazione TableAdapters di DataSet tipizzato .
Lascio questo come esercizio per il lettore.
Riepilogo
Quando si usano database relazionali, è comune che le query estraggono i dati da più tabelle correlate. Le sottoquery correlate e JOIN
s forniscono due tecniche diverse per l'accesso ai dati dalle tabelle correlate in una query. Nelle esercitazioni precedenti è stato usato in genere di sottoquery correlate perché TableAdapter non può generare INSERT
automaticamente istruzioni , UPDATE
e DELETE
per le query che coinvolgono JOIN
s. Anche se questi valori possono essere forniti manualmente, quando si usano istruzioni SQL ad hoc tutte le personalizzazioni verranno sovrascritte al termine della Configurazione guidata TableAdapter.
Fortunatamente, i tableAdapter creati con stored procedure non soffrono della stessa fragilità di quelle create usando istruzioni SQL ad hoc. Pertanto, è possibile creare un TableAdapter la cui query principale usa un oggetto JOIN
quando si usano stored procedure. In questa esercitazione è stato illustrato come creare un tableAdapter di questo tipo. È stata avviata l'uso di una JOIN
query -less SELECT
per la query principale di TableAdapter in modo che le stored procedure di inserimento, aggiornamento ed eliminazione corrispondenti vengano create automaticamente. Al termine della configurazione iniziale di TableAdapter, la SelectCommand
stored procedure è stata aumentata per usare ed JOIN
eseguire nuovamente la Configurazione guidata TableAdapter per aggiornare le EmployeesDataTable
colonne.
Eseguendo nuovamente la Configurazione guidata TableAdapter, le EmployeesDataTable
colonne vengono aggiornate automaticamente in modo da riflettere i campi dati restituiti dalla Employees_Select
stored procedure. In alternativa, è possibile aggiungere queste colonne manualmente a DataTable. Nell'esercitazione successiva si esaminerà l'aggiunta manuale di colonne a DataTable.
Buon programmatori!
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora 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 all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, disponibile all'indirizzo http://ScottOnWriting.NET.
Grazie speciale a
Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali di questa esercitazione sono stati Hilton Geisenow, David Suru e Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciami una riga in mitchell@4GuysFromRolla.com.