Delen via


De TableAdapter bijwerken voor het gebruik van JOINs (C#)

door Scott Mitchell

PDF downloaden

Wanneer u met een database werkt, is het gebruikelijk om gegevens aan te vragen die zijn verspreid over meerdere tabellen. Voor het ophalen van gegevens uit twee verschillende tabellen kunnen we een gecorreleerde subquery of een JOIN-bewerking gebruiken. In deze zelfstudie vergelijken we gecorreleerde subquery's en de JOIN-syntaxis voordat we kijken hoe u een TableAdapter maakt die een JOIN in de hoofdquery bevat.

Introductie

Met relationele databases zijn de gegevens waarmee we geïnteresseerd zijn in het werken vaak verspreid over meerdere tabellen. Wanneer u bijvoorbeeld productgegevens weergeeft, willen we waarschijnlijk de overeenkomstige categorie van elk product en de namen van leveranciers vermelden. De Products tabel heeft CategoryID en SupplierID de waarden, maar de werkelijke categorie- en leveranciersnamen bevinden zich respectievelijk in de Categories tabel en Suppliers tabellen.

Als u gegevens wilt ophalen uit een andere, gerelateerde tabel, kunnen we gecorreleerde subquery's of JOINs gebruiken. Een gecorreleerde subquery is een geneste SELECT query die verwijst naar kolommen in de buitenste query. In de zelfstudie Een Gegevenstoegangslaag maken hebben we bijvoorbeeld twee gecorreleerde subquery's in de ProductsTableAdapter hoofdquery gebruikt om de categorie- en leveranciersnamen voor elk product te retourneren. Een JOIN is een SQL-constructie waarmee gerelateerde rijen uit twee verschillende tabellen worden samengevoegd. We hebben een JOIN gebruikt in de zelfstudie Gegevensquery met de SqlDataSource Control om naast elk product categoriegegevens weer te geven.

De reden waarom we hebben afgezien van het gebruik van JOIN met de TableAdapters is vanwege beperkingen in de TableAdapter-wizard om automatisch overeenkomstige INSERT, UPDATE en DELETE uitspraken te genereren. Als de hoofdquery van TableAdapter meerdere JOIN's bevat, kan de TableAdapter de ad-hoc SQL-instructies of opgeslagen procedures voor zijn InsertCommand, UpdateCommand en DeleteCommand-eigenschappen niet automatisch aanmaken.

In deze handleiding zullen we kort de verschillen en overeenkomsten tussen gecorreleerde subquery’s en JOIN s bespreken voordat we verkennen hoe je een TableAdapter maakt die JOIN s in zijn hoofdquery bevat.

Gecorreleerde subquery's en s vergelijken enJOIN contrasteren

Herinner u zich dat de ProductsTableAdapter in de eerste zelfstudie in de Northwind DataSet gecorreleerde subquery's gebruikt om de overeenkomstige categorie en leveranciersnaam van elk product op te halen. De ProductsTableAdapter hoofdquery van de s wordt hieronder weergegeven.

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

De twee gecorreleerde subqueries (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) en (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) zijn SELECT query's die één waarde per product retourneren als een extra kolom in de kolomlijst van de buitenste SELECT verklaring.

Als alternatief kunt u met een JOIN de leverancier en categorienaam van elk product retourneren. De volgende query retourneert dezelfde uitvoer als de bovenstaande, maar gebruikt JOIN s in plaats van subquery's:

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

Een JOIN voegt de records uit de ene tabel samen met de records uit een andere tabel op basis van bepaalde criteria. In de bovenstaande query geeft de SQL Server bijvoorbeeld de LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID opdracht om elke productrecord samen te voegen met de categorierecord waarvan CategoryID de waarde overeenkomt met de productwaarde CategoryID . Met het samengevoegde resultaat kunnen we werken met de bijbehorende categorievelden voor elk product (zoals CategoryName).

Opmerking

JOIN s worden vaak gebruikt bij het opvragen van gegevens uit relationele databases. Als u nieuw bent in de JOIN syntaxis of een beetje moet opfrissen over het gebruik ervan, raad ik de SQL Join tutorial aan van W3 Schools. Lees ook de JOIN basisprincipes en subquery fundamentals van de SQL Books Online.

Omdat JOIN s en gecorreleerde subquery's beide kunnen worden gebruikt om gerelateerde gegevens op te halen uit andere tabellen, blijven veel ontwikkelaars hun hoofden krabben en zich afvragen welke benadering moet worden gebruikt. Alle SQL-goeroes die ik heb gesproken, hebben ongeveer hetzelfde gezegd, dat het niet echt belangrijk is voor prestaties, omdat SQL Server ongeveer identieke uitvoeringsplannen zal produceren. Hun advies is dan om de techniek te gebruiken waarmee u en uw team het meest vertrouwd zijn. Het is vermeldenswaard dat deze experts na het geven van dit advies onmiddellijk hun voorkeur voor JOIN boven gecorreleerde subqueries uiten.

Bij het bouwen van een Data Access-laag met behulp van getypte gegevenssets werken de hulpprogramma's beter bij het gebruik van subquery's. "In het bijzonder genereert de wizard van TableAdapters geen bijbehorende INSERT, UPDATE, en DELETE-instructies als de hoofdquery JOIN-elementen bevat, maar genereert deze instructies automatisch wanneer gecorreleerde subquery's worden gebruikt."

Om deze tekortkoming te onderzoeken, maakt u een tijdelijke Getypte DataSet in de ~/App_Code/DAL map. Kies er tijdens de wizard TableAdapter-configuratie voor om ad-hoc SQL-instructies te gebruiken en voer de volgende SELECT query in (zie afbeelding 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

Schermopname van het configuratie-wizardvenster voor de TableAdaptor met een query die JOINs bevat.

Afbeelding 1: Voer een hoofdquery in die s bevat JOIN (klik om de volledige afbeelding weer te geven)

De TableAdapter maakt standaard automatisch INSERT, UPDATE en DELETE instructies op basis van de hoofdquery. Als u op de knop Geavanceerd klikt, ziet u dat deze functie is ingeschakeld. Ondanks deze instelling kan de TableAdapter de INSERT, UPDATE, en DELETE instructies niet maken omdat de hoofdquery een JOIN bevat.

Schermopname van het venster Geavanceerde opties met het selectievakje Invoegen, Bijwerken en Verwijderen genereren ingeschakeld.

Afbeelding 2: Voer een hoofdquery in die s bevat JOIN

Klik op Voltooien om de wizard te voltooien. Op dit moment bevat de DataSet-ontwerper één TableAdapter met een gegevenstabel met kolommen voor elk veld dat geretourneerd wordt in de kolomlijst van de SELECT query. Dit omvat de CategoryName en SupplierName, zoals in afbeelding 3 wordt weergegeven.

De gegevenstabel bevat een kolom voor elk veld dat wordt geretourneerd in de kolomlijst

Afbeelding 3: De gegevenstabel bevat een kolom voor elk veld dat wordt geretourneerd in de lijst met kolommen

Hoewel de DataTable de juiste kolommen heeft, ontbreekt de TableAdapter aan waarden voor InsertCommandde bijbehorende , UpdateCommanden DeleteCommand eigenschappen. Als u dit wilt bevestigen, klikt u op TableAdapter in de ontwerpfunctie en gaat u vervolgens naar het venster Eigenschappen. Daar ziet u dat de InsertCommand, UpdateCommanden DeleteCommand eigenschappen zijn ingesteld op (Geen).

De eigenschappen InsertCommand, UpdateCommand en DeleteCommand zijn ingesteld op (Geen)

Afbeelding 4: De InsertCommandeigenschappen en UpdateCommandeigenschappen DeleteCommand zijn ingesteld op (geen) (klik om de afbeelding op volledige grootte weer te geven)

Om deze tekortkoming te omzeilen, kunnen we handmatig de SQL-instructies en -parameters voor de InsertCommand, UpdateCommand, en DeleteCommand eigenschappen opgeven via het venster Eigenschappen. U kunt ook beginnen met het configureren van de hoofdquery van TableAdapter om geenJOIN s op te nemen. Hierdoor kunnen de INSERT, UPDATE en DELETE instructies automatisch voor ons worden gegenereerd. Nadat de wizard is voltooid, kunnen we de TableAdapters SelectCommand handmatig bijwerken vanuit het venster Eigenschappen, zodat deze de JOIN syntaxis bevat.

Hoewel deze benadering werkt, is het zeer broos wanneer u ad-hoc SQL-query's gebruikt, omdat de hoofdquery van TableAdapter op elk moment opnieuw wordt geconfigureerd via de wizard, de automatisch gegenereerde INSERTen UPDATEDELETE instructies opnieuw worden gemaakt. Dat betekent dat alle aanpassingen die we later hebben aangebracht verloren gaan als we met de rechtermuisknop op de TableAdapter hebben geklikt, in het contextmenu configureren hebben gekozen en de wizard opnieuw hebben voltooid.

De broosheid van de INSERT-, UPDATE- en DELETE-instructies die automatisch door de TableAdapter gegenereerd zijn, is gelukkig beperkt tot ad-hoc SQL-instructies. Als uw TableAdapter gebruikmaakt van opgeslagen procedures, kunt u de opgeslagen procedures SelectCommand, InsertCommand, UpdateCommand, of DeleteCommand aanpassen en de wizard voor TableAdapter-configuratie opnieuw uitvoeren zonder dat u zich zorgen hoeft te maken dat de opgeslagen procedures worden gewijzigd.

In de volgende stappen maken we een TableAdapter die in eerste instantie een hoofdquery gebruikt die alle s weglaat JOIN , zodat de bijbehorende opgeslagen procedures voor invoegen, bijwerken en verwijderen automatisch worden gegenereerd. Vervolgens wordt de SelectCommand functie bijgewerkt, zodat er een JOIN wordt gebruikt die extra kolommen uit gerelateerde tabellen retourneert. Ten slotte maken we een bijbehorende Business Logic Layer-klasse en demonstreren we het gebruik van TableAdapter op een ASP.NET webpagina.

Stap 1: De TableAdapter maken met behulp van een vereenvoudigde hoofdquery

Voor deze handleiding voegen we een TableAdapter en een sterk getypte DataTable toe voor de Employees tabel in de NorthwindWithSprocs DataSet. De Employees tabel bevat een ReportsTo veld dat de EmployeeID manager van de werknemer heeft opgegeven. Werknemer Anne Dodsworth heeft bijvoorbeeld de ReportTo waarde 5, wat de EmployeeID waarde van Steven Buchanan is. Daarom meldt Anne aan Steven, haar manager. Naast het rapporteren van de waarde van ReportsTo elke werknemer, willen we mogelijk ook de naam van hun manager ophalen. Dit kan worden bereikt met behulp van een JOIN. Wanneer u een JOIN tabeladapter maakt, sluit dit de mogelijkheid uit dat de wizard automatisch de bijbehorende mogelijkheden voor invoegen, bijwerken en verwijderen genereert. Daarom beginnen we met het maken van een TableAdapter waarvan de hoofdquery geen JOIN s bevat. Vervolgens werken we in stap 2 de opgeslagen hoofdqueryprocedure bij om de naam van de manager op te halen via een JOIN.

Open eerst de NorthwindWithSprocs DataSet in de ~/App_Code/DAL map. Klik met de rechtermuisknop op de ontwerpfunctie, selecteer de optie Toevoegen in het contextmenu en kies het menu-item TableAdapter. Hiermee wordt de wizard TableAdapter-configuratie gestart. Zoals in afbeelding 5 wordt weergegeven, moet u de wizard nieuwe opgeslagen procedures laten maken en op Volgende klikken. Raadpleeg de tutorial Nieuwe opgeslagen procedures maken voor de TableAdapters van het getypte DataSet voor een opfriscursus over het maken van nieuwe opgeslagen procedures vanuit de TableAdapter-wizard.

Selecteer de optie Nieuwe opgeslagen procedures maken

Afbeelding 5: Selecteer de optie Nieuwe opgeslagen procedures maken (klik hier om de volledige afbeelding weer te geven)

Gebruik de volgende SELECT instructie voor de hoofdquery van TableAdapter:

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

Omdat deze query geen JOIN's bevat, maakt de TableAdapter-wizard automatisch opgeslagen procedures met de overeenkomstige INSERT, UPDATE en DELETE-instructies, evenals een opgeslagen procedure voor het uitvoeren van de hoofdquery.

Met de volgende stap kunnen we de opgeslagen procedures van TableAdapter een naam geven. Gebruik de namenEmployees_Select, Employees_Insert, en Employees_UpdateEmployees_Delete, zoals wordt weergegeven in afbeelding 6.

De opgeslagen procedures van TableAdapter een naam opgeven

Afbeelding 6: Geef de opgeslagen procedures van TableAdapter een naam (klik hier om de afbeelding op volledige grootte weer te geven)

In de laatste stap wordt ons gevraagd om de TableAdapter-methoden een naam te geven. Gebruik Fill en GetEmployees als methodenamen. Zorg er ook voor dat u het selectievakje "Maak methoden om updates rechtstreeks naar de database te sturen" (GenerateDBDirectMethods) ingeschakeld laat.

Noem de methoden van TableAdapter Fill en GetEmployees

Afbeelding 7: Geef de TableAdapter-methoden Fill een naam en GetEmployees (klik hier om de volledige afbeelding weer te geven)

Nadat u de wizard hebt voltooid, neemt u even de tijd om de opgeslagen procedures in de database te bekijken. U ziet vier nieuwe: Employees_Select, Employees_Insert, Employees_Updateen Employees_Delete. Inspecteer vervolgens de zojuist gemaakte EmployeesDataTable en EmployeesTableAdapter. De gegevenstabel bevat een kolom voor elk veld dat wordt geretourneerd door de hoofdquery. Klik op TableAdapter en ga vervolgens naar het venster Eigenschappen. Daar ziet u dat de InsertCommand, UpdateCommanden DeleteCommand eigenschappen correct zijn geconfigureerd om de bijbehorende opgeslagen procedures aan te roepen.

De TableAdapter bevat mogelijkheden voor invoegen, bijwerken en verwijderen

Afbeelding 8: De TableAdapter bevat mogelijkheden voor invoegen, bijwerken en verwijderen (klik om de volledige afbeelding weer te geven)

Met de opgeslagen procedures invoegen, bijwerken en verwijderen die automatisch zijn gemaakt en de InsertCommand, UpdateCommanden DeleteCommand eigenschappen correct geconfigureerd, zijn we klaar om de SelectCommand opgeslagen procedure aan te passen om aanvullende informatie over elke werknemermanager te retourneren. We moeten de opgeslagen procedure Employees_Select bijwerken om een JOIN te gebruiken en de FirstName- en LastName-waarden van de manager te retourneren. Nadat de opgeslagen procedure is bijgewerkt, moeten we de gegevenstabel bijwerken zodat deze deze extra kolommen bevat. Deze twee taken worden in stap 2 en 3 behandeld.

Stap 2: De opgeslagen procedure aanpassen om eenJOIN op te nemen

Ga eerst naar Server Explorer, zoom in op de map Opgeslagen procedures van de Northwind-database en open de Employees_Select opgeslagen procedure. Als u deze opgeslagen procedure niet ziet, klikt u met de rechtermuisknop op de map Opgeslagen procedures en kiest u Vernieuwen. Werk de opgeslagen procedure bij zodat deze gebruikmaakt van een LEFT JOIN om de voor- en achternaam van de manager te retourneren:

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

Nadat u de SELECT instructie hebt bijgewerkt, slaat u de wijzigingen op door naar het menu Bestand te gaan en Opslaan Employees_Selectte kiezen. U kunt ook op het pictogram Opslaan in de werkbalk klikken of op Ctrl+S drukken. Nadat u de wijzigingen hebt opgeslagen, klikt u met de rechtermuisknop op de Employees_Select opgeslagen procedure in Server Explorer en kiest u Uitvoeren. Hiermee wordt de opgeslagen procedure uitgevoerd en worden de resultaten weergegeven in het uitvoervenster (zie afbeelding 9).

De resultaten van opgeslagen procedures worden weergegeven in het uitvoervenster

Afbeelding 9: De resultaten van opgeslagen procedures worden weergegeven in het uitvoervenster (klik om de afbeelding op volledige grootte weer te geven)

Stap 3: de kolommen van de gegevenstabel bijwerken

Op dit moment retourneert de Employees_Select opgeslagen procedure ManagerFirstName en ManagerLastName waarden, maar EmployeesDataTable mist deze kolommen. Deze ontbrekende kolommen kunnen op twee manieren aan de gegevenstabel worden toegevoegd:

  • Handmatig : klik met de rechtermuisknop op de gegevenstabel in de DataSet Designer en kies kolom in het menu Toevoegen. Vervolgens kunt u de kolom een naam opgeven en de eigenschappen dienovereenkomstig instellen.
  • Automatisch : de wizard TableAdapter-configuratie werkt de kolommen van de Gegevenstabel bij zodat deze overeenkomen met de velden die door de SelectCommand opgeslagen procedure worden geretourneerd. Wanneer u ad-hoc SQL-instructies gebruikt, worden ook de InsertCommand, UpdateCommand en DeleteCommand eigenschappen van de wizard verwijderd, omdat het SelectCommand nu een JOIN bevat. Maar wanneer u opgeslagen procedures gebruikt, blijven deze opdrachteigenschappen intact.

We hebben in eerdere handleidingen handmatig DataTable-kolommen toegevoegd, waaronder Master/Detail Using a Bulleted List of Master Records with a Details DataList en Uploading Files, en we zullen dit proces in meer detail opnieuw bekijken in onze volgende handleiding. Voor deze zelfstudie laten we de automatische benadering via de TableAdapter-configuratiewizard gebruiken.

Klik eerst met de rechtermuisknop op de EmployeesTableAdapter knop en selecteer Configureren in het contextmenu. Hiermee wordt de wizard TableAdapter-configuratie weergegeven, waarin de opgeslagen procedures worden vermeld die worden gebruikt voor het selecteren, invoegen, bijwerken en verwijderen, samen met de retourwaarden en parameters (indien van toepassing). In afbeelding 10 ziet u deze wizard. Hier ziet u dat de Employees_Select opgeslagen procedure nu de ManagerFirstName en ManagerLastName velden retourneert.

De wizard toont de bijgewerkte kolomlijst voor de Employees_Select Opgeslagen procedure

Afbeelding 10: De wizard toont de bijgewerkte kolomlijst voor de Employees_Select opgeslagen procedure (klik om de afbeelding op volledige grootte weer te geven)

Voltooi de wizard door op Voltooien te klikken. Wanneer u terugkeert naar de DataSet Designer, bevat deze EmployeesDataTable twee extra kolommen: ManagerFirstName en ManagerLastName.

De EmployeesDataTable bevat twee nieuwe kolommen

Afbeelding 11: Bevat EmployeesDataTable twee nieuwe kolommen (klik om de afbeelding volledig weer te geven)

Ter illustratie dat de bijgewerkte Employees_Select opgeslagen procedure van kracht is en dat de mogelijkheden voor invoegen, bijwerken en verwijderen van de TableAdapter nog steeds functioneel zijn, maken we een webpagina waarmee gebruikers werknemers kunnen bekijken en verwijderen. Voordat we een dergelijke pagina maken, moeten we echter eerst een nieuwe klasse maken in de bedrijfslogicalaag voor het werken met werknemers uit de NorthwindWithSprocs DataSet. In stap 4 maken we een EmployeesBLLWithSprocs klasse. In stap 5 gebruiken we deze klasse vanaf een ASP.NET pagina.

Stap 4: De bedrijfslogicalaag implementeren

Maak een nieuw klassebestand in de map met de ~/App_Code/BLL naam EmployeesBLLWithSprocs.cs. Deze klasse bootst de semantiek van de bestaande EmployeesBLL klasse na, alleen deze nieuwe biedt minder methoden en maakt gebruik van de NorthwindWithSprocs DataSet (in plaats van de Northwind DataSet). Voeg de volgende code toe aan de klasse 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;
    }
}

De klasse EmployeesBLLWithSprocs eigenschap Adapter geeft een exemplaar van de NorthwindWithSprocs DataSet EmployeesTableAdapter terug. Dit wordt gebruikt door de klasse s GetEmployees en DeleteEmployee methoden. De GetEmployees methode roept de bijbehorende EmployeesTableAdapterGetEmployees methode aan, die de Employees_Select opgeslagen procedure uitvoert en de resultaten in een EmployeeDataTable plaatst. De DeleteEmployee methode roept op vergelijkbare wijze de EmployeesTableAdapterDelete methode aan, die de Employees_Delete opgeslagen procedure aanroept.

Stap 5: Werken met de gegevens in de presentatielaag

Nu de EmployeesBLLWithSprocs klas is voltooid, zijn we klaar om met werknemersgegevens te werken via een ASP.NET pagina. Open de JOINs.aspx pagina in de AdvancedDAL map en sleep een GridView van de Werkset naar de Ontwerper, waarbij u de eigenschap ID instelt op Employees. Vervolgens koppelt u het raster vanuit de smart tag van GridView aan een nieuw ObjectDataSource-besturingselement met de naam EmployeesDataSource.

Configureer de ObjectDataSource om de EmployeesBLLWithSprocs klasse te gebruiken en zorg ervoor dat op de tabbladen SELECT en DELETE de methoden GetEmployees en DeleteEmployee zijn geselecteerd in de vervolgkeuzelijsten. Klik op Voltooien om de configuratie van ObjectDataSource te voltooien.

De ObjectDataSource configureren voor het gebruik van de klasse EmployeesBLLWithSprocs

Afbeelding 12: De ObjectDataSource configureren om de EmployeesBLLWithSprocs klasse te gebruiken (klik om de afbeelding op volledige grootte weer te geven)

Laat de ObjectDataSource de methoden GetEmployees en DeleteEmployee gebruiken

Afbeelding 13: Laat de ObjectDataSource de GetEmployees en DeleteEmployee methoden gebruiken (klik om de afbeelding op volledige grootte weer te geven)

Visual Studio voegt een BoundField toe aan de GridView voor elk van de EmployeesDataTable kolommen. Verwijder al deze BoundFields, met uitzondering van Title, LastName, FirstName, ManagerFirstName en ManagerLastName en hernoem de HeaderText-eigenschappen voor de laatste vier BoundFields respectievelijk in Achternaam, Voornaam, Voornaam van de Manager en Achternaam van de Manager.

Als u wilt dat gebruikers werknemers van deze pagina kunnen verwijderen, moeten we twee dingen doen. Geef eerst de GridView opdracht om verwijdermogelijkheden te bieden door de optie Verwijderen in te schakelen via de smart tag. Wijzig ten tweede de eigenschap OldValuesParameterFormatString van ObjectDataSource van de waarde die is ingesteld door de ObjectDataSource-wizard (original_{0}) naar de standaardwaarde ({0}). Nadat u deze wijzigingen hebt aangebracht, moeten de declaratieve markeringen van GridView en ObjectDataSource er ongeveer als volgt uitzien:

<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>

Test de pagina door deze te bezoeken via een browser. Zoals in afbeelding 14 wordt weergegeven, worden op de pagina elke werknemer en de naam van zijn of haar manager vermeld (ervan uitgaande dat ze er een hebben).

De JOIN in de 'Employees_Select' opgeslagen procedure geeft de naam van de manager terug

Afbeelding 14: De JOIN in de Employees_Select opgeslagen procedure retourneert de naam van de manager (klik om de volledige afbeelding weer te geven)

Als u op de knop Verwijderen klikt, wordt de werkstroom voor verwijderen gestart. Dit resulteert in de uitvoering van de Employees_Delete opgeslagen procedure. De poging tot uitvoering van instructie DELETE in de opgeslagen procedure mislukt echter vanwege een schending van een foreign key-beperking (zie afbeelding 15). In het bijzonder heeft elke werknemer een of meer records in de Orders tabel, waardoor het verwijderen mislukt.

Het verwijderen van een medewerker met overeenkomende orders resulteert in een schending van een foreign key-beperking

Afbeelding 15: Een werknemer verwijderen met overeenkomende orders resulteert in een schending van een foreign key constraint (Klik om de afbeelding volledig weer te geven)

Als u wilt toestaan dat een werknemer wordt verwijderd, kunt u het volgende doen:

  • Werk de beperking van de refererende sleutel bij om trapsgewijs te verwijderen,
  • Verwijder de records handmatig uit de Orders tabel voor de werknemers die u wilt verwijderen of
  • Werk de Employees_Delete opgeslagen procedure bij om eerst de gerelateerde records uit de Orders tabel te verwijderen voordat u de Employees record verwijdert. We hebben deze techniek besproken in de zelfstudie Bestaande opgeslagen procedures gebruiken voor Getypte DataSet TableAdapters.

Ik laat dit achter als oefening voor de lezer.

Samenvatting

Wanneer u met relationele databases werkt, is het gebruikelijk dat query's hun gegevens ophalen uit meerdere gerelateerde tabellen. Gecorreleerde subquery's en JOIN s bieden twee verschillende technieken voor het openen van gegevens uit gerelateerde tabellen in een query. In eerdere zelfstudies hebben we het meest gebruik gemaakt van gecorreleerde subquery's, omdat de TableAdapter INSERT, UPDATE, en DELETE instructies voor query's met betrekking tot JOIN s niet automatisch kan genereren. Hoewel deze waarden handmatig kunnen worden opgegeven, worden bij het gebruik van ad-hoc SQL-instructies eventuele aanpassingen overschreven wanneer de wizard TableAdapter-configuratie is voltooid.

Gelukkig hebben TableAdapters die zijn gemaakt met behulp van opgeslagen procedures, niet dezelfde broosheid als die zijn gemaakt met behulp van ad-hoc SQL-instructies. Daarom is het haalbaar om een TableAdapter te maken waarvan de hoofdquery gebruikmaakt van een JOIN wanneer opgeslagen procedures worden gebruikt. In deze zelfstudie hebben we gezien hoe u een dergelijke TableAdapter maakt. We zijn begonnen met het gebruik van een query zonder JOINSELECT voor de hoofdquery van TableAdapter, zodat de bijbehorende opgeslagen procedures automatisch gegenereerd worden voor invoegen, bijwerken en verwijderen. Nu de initiële configuratie van de TableAdapter is voltooid, hebben we de SelectCommand opgeslagen procedure aangepast om een JOIN te gebruiken en de TableAdapter Configuration wizard opnieuw uitgevoerd om de EmployeesDataTable kolommen bij te werken.

Het opnieuw uitvoeren van de wizard TableAdapter-configuratie heeft de kolommen automatisch bijgewerkt om de EmployeesDataTable gegevensvelden weer te geven die door de Employees_Select opgeslagen procedure worden geretourneerd. U kunt deze kolommen ook handmatig toevoegen aan de gegevenstabel. In de volgende zelfstudie gaan we handmatig kolommen toevoegen aan de DataTable.

Veel plezier met programmeren!

Over de auteur

Scott Mitchell, auteur van zeven ASP/ASP.NET-boeken en oprichter van 4GuysFromRolla.com, werkt sinds 1998 met Microsoft-webtechnologieën. Scott werkt als onafhankelijk consultant, trainer en schrijver. Zijn laatste boek is Sams Teach Yourself ASP.NET 2.0 in 24 uur. Hij kan worden bereikt op mitchell@4GuysFromRolla.com.

Speciale dank aan

Deze tutorialreeks is beoordeeld door veel behulpzame beoordelers. Hoofdrevisoren voor deze zelfstudie waren Hilton Geisenow, David Suru en Teresa Murphy. Bent u geïnteresseerd in het bekijken van mijn aanstaande MSDN-artikelen? Zo ja, laat iets van je horen via mitchell@4GuysFromRolla.com.