Freigeben über


Aktualisieren des TableAdapter-Steuerelements für die Verwendung von Verknüpfungen (C#)

von Scott Mitchell

PDF herunterladen

Bei der Arbeit mit einer Datenbank werden häufig Daten anzufordern, die auf mehrere Tabellen verteilt sind. Zum Abrufen von Daten aus zwei verschiedenen Tabellen können wir entweder eine korrelierte Unterabfrage oder einen JOIN-Vorgang verwenden. In diesem Tutorial vergleichen wir korrelierte Unterabfragen und die JOIN-Syntax, bevor wir uns mit dem Erstellen eines TableAdapters, der eine JOIN-Abfrage in der Standard Abfrage enthält, ansehen.

Einführung

Bei relationalen Datenbanken sind die Daten, mit denen wir arbeiten möchten, häufig auf mehrere Tabellen verteilt. Beispielsweise möchten wir beim Anzeigen von Produktinformationen wahrscheinlich die entsprechenden Produktkategorien und Lieferantennamen auflisten. Die Products Tabelle enthält CategoryID Werte undSupplierID, aber die tatsächlichen Kategorie- und Lieferantennamen befinden sich in den Tabellen bzwSuppliers. in den Categories Tabellen.

Um Informationen aus einer anderen, verwandten Tabelle abzurufen, können wir entweder korrelierte Unterabfragen oder JOINs verwenden. Eine korrelierte Unterabfrage ist eine geschachtelte SELECT Abfrage, die auf Spalten in der äußeren Abfrage verweist. Beispielsweise haben wir im Tutorial Erstellen einer Datenzugriffsebene zwei korrelierte Unterabfragen in der ProductsTableAdapter s-Standard-Abfrage verwendet, um die Kategorie- und Lieferantennamen für jedes Produkt zurückzugeben. A JOIN ist ein SQL-Konstrukt, das verwandte Zeilen aus zwei verschiedenen Tabellen zusammenführt. Wir haben ein im Tutorial Abfragen von Daten mit dem SqlDataSource-Steuerelement verwendetJOIN, um Kategorieinformationen neben jedem Produkt anzuzeigen.

Der Grund, warum wir auf die Verwendung JOIN von s mit den TableAdapters verzichtet haben, liegt an Einschränkungen im TableAdapter-Assistenten zum automatischen Generieren entsprechender INSERT, , UPDATEund DELETE -Anweisungen. Genauer gesagt, wenn die TableAdapter-Standard-Abfrage beliebige JOIN s enthält, kann TableAdapter die Ad-hoc-SQL-Anweisungen oder gespeicherten Prozeduren für die InsertCommandEigenschaften , UpdateCommandund nicht DeleteCommand automatisch erstellen.

In diesem Tutorial vergleichen wir kurz korrelierte Unterabfragen und s, JOIN bevor wir untersuchen, wie ein TableAdapter erstellt wird, der s in der Standard Abfrage enthältJOIN.

Vergleichen und Kontrastieren korrelierter Unterabfragen undJOIN s

Denken Sie daran, dass die ProductsTableAdapter im ersten Tutorial im Northwind DataSet erstellte korrelierte Unterabfragen verwendet, um die entsprechenden Produktkategorien und lieferantennamen zurückzubringen. Die ProductsTableAdapter Abfrage s Standard ist unten dargestellt.

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

Die beiden korrelierten Unterabfragen - (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) und - sind SELECT Abfragen, die einen einzelnen Wert pro Produkt als zusätzliche Spalte in der Spaltenliste der äußeren SELECT Anweisung (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) zurückgeben.

Alternativ kann ein JOIN verwendet werden, um den Lieferanten- und Kategorienamen jedes Produkts zurückzugeben. Die folgende Abfrage gibt dieselbe Ausgabe wie die oben genannte zurück, verwendet JOIN jedoch s anstelle von Unterabfragen:

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

Ein JOIN führt die Datensätze aus einer Tabelle anhand einiger Kriterien mit Datensätzen aus einer anderen Tabelle zusammen. In der obigen Abfrage wird beispielsweise SQL Server LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID angewiesen, jeden Produktdatensatz mit dem Kategoriedatensatz zusammenzuführen, dessen CategoryID Wert mit dem Wert des Produkts CategoryID übereinstimmt. Das zusammengeführte Ergebnis ermöglicht es uns, mit den entsprechenden Kategoriefeldern für jedes Produkt (z CategoryName. B. ) zu arbeiten.

Hinweis

JOIN s werden häufig beim Abfragen von Daten aus relationalen Datenbanken verwendet. Wenn Sie noch nicht mit der JOIN Syntax sind oder die Verwendung etwas auffrischen müssen, empfehle ich das Tutorial zum SQL Join an W3 Schools. Lesenswert sind auch die JOIN Abschnitte Fundamentals und Subquery Fundamentals der SQL-Onlinedokumentation.

Da JOIN s und korrelierte Unterabfragen beide verwendet werden können, um verwandte Daten aus anderen Tabellen abzurufen, müssen sich viele Entwickler den Kopf zerkratzen und fragen sich, welcher Ansatz verwendet werden soll. Alle SQL-Gurus, mit denen ich gesprochen habe, haben ungefähr dasselbe gesagt, dass es in Bezug auf die Leistung keine Rolle spielt, da SQL Server ungefähr identische Ausführungspläne erstellen wird. Ihr Rat ist also, die Technik zu verwenden, mit der Sie und Ihr Team am besten vertraut sind. Es ist zu beachten, dass diese Experten nach der Vermittlung dieses Hinweises sofort ihre Vorliebe für JOIN s gegenüber korrelierten Unterabfragen zum Ausdruck bringen.

Beim Erstellen einer Datenzugriffsebene mit typisierten DataSets funktionieren die Tools besser, wenn Unterabfragen verwendet werden. Insbesondere generiert der TableAdapter-Assistent die entsprechenden INSERTAnweisungen , UPDATEund DELETE nicht automatisch, wenn die Standard Abfrage s JOIN enthält, sondern automatisch diese Anweisungen generiert, wenn korrelierte Unterabfragen verwendet werden.

Um dieses Manko zu untersuchen, erstellen Sie ein temporäres typisiertes DataSet im ~/App_Code/DAL Ordner. Wählen Sie während des TableAdapter-Konfigurations-Assistenten ad-hoc-SQL-Anweisungen aus, und geben Sie die folgende SELECT Abfrage ein (siehe Abbildung 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: Fenster des TableAdaptor-Konfigurations-Assistenten mit einer eingegebenen Abfrage, die JOINs enthält

Abbildung 1: Geben Sie eine Hauptabfrage ein, die s enthält JOIN (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Standardmäßig erstellt INSERTtableAdapter automatisch , , UPDATEund DELETE die Anweisungen basierend auf der Standard Abfrage. Wenn Sie auf die Schaltfläche Erweitert klicken, können Sie sehen, dass dieses Feature aktiviert ist. Trotz dieser Einstellung kann der TableAdapter die INSERTAnweisungen , UPDATEund DELETE nicht erstellen, da die Standard Abfrage einen JOINenthält.

Screenshot: Fenster

Abbildung 2: Geben Sie eine Hauptabfrage ein, die s enthält JOIN .

Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen. An diesem Punkt enthält Ihr DataSet-Designer einen einzelnen TableAdapter mit einer DataTable mit Spalten für jedes der felder, die in der Spaltenliste der SELECT Abfrage zurückgegeben werden. Dies schließt die CategoryName und SupplierNameein, wie Abbildung 3 zeigt.

Die DataTable enthält eine Spalte für jedes in der Spaltenliste zurückgegebene Feld.

Abbildung 3: Die DataTable enthält eine Spalte für jedes in der Spaltenliste zurückgegebene Feld.

Während die DataTable über die entsprechenden Spalten verfügt, fehlen dem TableAdapter Werte für die InsertCommandEigenschaften , UpdateCommand, und DeleteCommand . Um dies zu bestätigen, klicken Sie auf den TableAdapter in der Designer, und wechseln Sie dann zum Eigenschaftenfenster. Dort sehen Sie, dass die InsertCommandEigenschaften , UpdateCommandund DeleteCommand auf (None) festgelegt sind.

Die Eigenschaften InsertCommand, UpdateCommand und DeleteCommand sind auf (None) festgelegt.

Abbildung 4: Die InsertCommandEigenschaften , UpdateCommandund DeleteCommand sind auf festgelegt (Keine) (Klicken Sie, um das bild in voller Größe anzuzeigen)

Um diesen Mangel zu umgehen, können wir die SQL-Anweisungen und -Parameter für die InsertCommandEigenschaften , UpdateCommandund DeleteCommand manuell über die Eigenschaftenfenster bereitstellen. Alternativ können wir zunächst die TableAdapter s-Standard-Abfrage so konfigurieren, dass sie keineJOIN s enthält. Dadurch können die INSERTAnweisungen , UPDATEund DELETE automatisch für uns generiert werden. Nach Abschluss des Assistenten können wir die TableAdapter s SelectCommand manuell aus dem Eigenschaftenfenster aktualisieren, sodass er die JOIN Syntax enthält.

Obwohl dieser Ansatz funktioniert, ist er bei Verwendung von Ad-hoc-SQL-Abfragen sehr spröde, da die automatisch generierten INSERT, UPDATEund DELETE -Anweisungen jedes Mal neu erstellt werden, wenn die TableAdapter-Standard Abfrage über den Assistenten neu konfiguriert wird. Das bedeutet, dass alle später vorgenommenen Anpassungen verloren gehen, wenn wir mit der rechten Maustaste auf den TableAdapter klicken, im Kontextmenü Konfigurieren auswählen und den Assistenten erneut abgeschlossen haben.

Die Brüchigkeit der automatisch generierten INSERT, UPDATE, und DELETE -Anweisungen von TableAdapter ist glücklicherweise auf Ad-hoc-SQL-Anweisungen beschränkt. Wenn Ihr TableAdapter gespeicherte Prozeduren verwendet, können Sie die gespeicherten SelectCommandProzeduren, InsertCommand, UpdateCommandoder DeleteCommand anpassen und den TableAdapter-Konfigurations-Assistenten erneut ausführen, ohne befürchten zu müssen, dass die gespeicherten Prozeduren geändert werden.

In den nächsten Schritten erstellen wir einen TableAdapter, der zunächst eine Standard Abfrage verwendet, die alle JOIN s auslässt, sodass die entsprechenden gespeicherten Prozeduren zum Einfügen, Aktualisieren und Löschen automatisch generiert werden. Anschließend wird aktualisiert SelectCommand , dass ein JOIN verwendet wird, das zusätzliche Spalten aus verwandten Tabellen zurückgibt. Abschließend erstellen wir eine entsprechende Business Logic Layer-Klasse und veranschaulichen die Verwendung von TableAdapter in einer ASP.NET Webseite.

Schritt 1: Erstellen des TableAdapter mithilfe einer vereinfachten Hauptabfrage

In diesem Tutorial fügen wir einen TableAdapter und eine stark typisierte DataTable für die Employees Tabelle im NorthwindWithSprocs DataSet hinzu. Die Employees Tabelle enthält ein ReportsTo Feld, das den EmployeeID des Vorgesetzten des Mitarbeiters angibt. Beispielsweise hat die Mitarbeiterin Anne Dodsworth einen ReportTo Wert von 5, der EmployeeID von Steven Buchanan. Anne meldet sich daher an Steven, ihren Manager. Neben der Meldung des Werts jedes Mitarbeiters ReportsTo können wir auch den Namen des Vorgesetzten abrufen. Dies kann mithilfe von JOINerreicht werden. Die Verwendung eines JOIN beim anfänglichen Erstellen des TableAdapter verhindert jedoch, dass der Assistent automatisch die entsprechenden Einfüge-, Update- und Löschfunktionen generiert. Daher erstellen wir zunächst einen TableAdapter, dessen Standard Abfrage keine JOIN s enthält. Anschließend aktualisieren wir in Schritt 2 die Standard gespeicherte Abfrageprozedur, um den Namen des Managers über einen JOINabzurufen.

Öffnen Sie zunächst das NorthwindWithSprocs DataSet im ~/App_Code/DAL Ordner. Klicken Sie mit der rechten Maustaste auf den Designer, wählen Sie im Kontextmenü die Option Hinzufügen aus, und wählen Sie das Menüelement TableAdapter aus. Dadurch wird der TableAdapter-Konfigurations-Assistent gestartet. Wie in Abbildung 5 dargestellt, lassen Sie den Assistenten neue gespeicherte Prozeduren erstellen, und klicken Sie auf Weiter. Eine Aktualisierung zum Erstellen neuer gespeicherter Prozeduren über den TableAdapter-Assistenten finden Sie im Tutorial Erstellen neuer gespeicherter Prozeduren für das TableAdapters-Tutorial typisierte DataSet s .

Wählen Sie die Option Neue gespeicherte Prozeduren erstellen aus.

Abbildung 5: Wählen Sie die Option Neue gespeicherte Prozeduren erstellen aus (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Verwenden Sie die folgende SELECT Anweisung für die TableAdapter-Standard-Abfrage:

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

Da diese Abfrage keine JOIN s enthält, erstellt der TableAdapter-Assistent automatisch gespeicherte Prozeduren mit den entsprechenden INSERTAnweisungen , UPDATEund DELETE sowie eine gespeicherte Prozedur zum Ausführen der Standard Abfrage.

Im folgenden Schritt können wir die gespeicherten TableAdapter-Prozeduren benennen. Verwenden Sie die Namen Employees_Select, Employees_Insert, Employees_Updateund Employees_Delete, wie in Abbildung 6 dargestellt.

Benennen Sie die gespeicherten TableAdapter-Prozeduren.

Abbildung 6: Benennen Sie die gespeicherten Prozeduren des TableAdapters (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Im letzten Schritt werden wir aufgefordert, die TableAdapter-Methoden zu benennen. Verwenden Sie Fill und GetEmployees als Methodennamen. Achten Sie außerdem darauf, das Kontrollkästchen Methoden erstellen, um Updates direkt an die Datenbank zu senden (GenerateDBDirectMethods) aktiviert.

Nennen Sie die TableAdapter-Methoden Fill und GetEmployees.

Abbildung 7: Benennen Sie die TableAdapter-Methoden Fill und GetEmployees (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Nehmen Sie sich nach Abschluss des Assistenten einen Moment Zeit, um die gespeicherten Prozeduren in der Datenbank zu untersuchen. Es sollten vier neue angezeigt werden: Employees_Select, Employees_Insert, Employees_Updateund Employees_Delete. Überprüfen Sie als Nächstes die EmployeesDataTable soeben erstellte und EmployeesTableAdapter . Die DataTable enthält eine Spalte für jedes Feld, das von der Standard-Abfrage zurückgegeben wird. Klicken Sie auf TableAdapter, und wechseln Sie dann zum Eigenschaftenfenster. Dort sehen Sie, dass die InsertCommandEigenschaften , UpdateCommandund DeleteCommand ordnungsgemäß konfiguriert sind, um die entsprechenden gespeicherten Prozeduren aufzurufen.

Der TableAdapter umfasst Funktionen zum Einfügen, Aktualisieren und Löschen.

Abbildung 8: Der TableAdapter enthält Die Funktionen Einfügen, Aktualisieren und Löschen (klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nachdem die gespeicherten Prozeduren zum Einfügen, Aktualisieren und Löschen automatisch erstellt wurden und die InsertCommandEigenschaften , UpdateCommandund DeleteCommand ordnungsgemäß konfiguriert sind, können wir die SelectCommand gespeicherte s-Prozedur anpassen, um zusätzliche Informationen zu den vorgesetzten Mitarbeitern zurückzugeben. Insbesondere müssen wir die Employees_Select gespeicherte Prozedur aktualisieren, um eine JOIN zu verwenden und die Vorgesetzten- FirstName und LastName -Werte zurückzugeben. Nachdem die gespeicherte Prozedur aktualisiert wurde, müssen wir die DataTable aktualisieren, damit sie diese zusätzlichen Spalten enthält. Diese beiden Aufgaben werden in Den Schritten 2 und 3 behandelt.

Schritt 2: Anpassen der gespeicherten Prozedur, um eine einzuschließenJOIN

Navigieren Sie zunächst zum Server-Explorer, führen Sie einen Drilldown in den Ordner gespeicherte Prozeduren der Northwind-Datenbank durch, und öffnen Sie die Employees_Select gespeicherte Prozedur. Wenn diese gespeicherte Prozedur nicht angezeigt wird, klicken Sie mit der rechten Maustaste auf den Ordner Gespeicherte Prozeduren, und wählen Sie Aktualisieren aus. Aktualisieren Sie die gespeicherte Prozedur so, dass sie einen LEFT JOIN verwendet, um den Vor- und Nachnamen des Vorgesetzten zurückzugeben:

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

Nachdem Sie die SELECT Anweisung aktualisiert haben, speichern Sie die Änderungen, indem Sie zum Menü Datei wechseln und Speichern Employees_Selectauswählen. Alternativ können Sie auf der Symbolleiste auf das Symbol Speichern klicken oder STRG+S drücken. Klicken Sie nach dem Speichern der Änderungen mit der rechten Maustaste auf die Employees_Select gespeicherte Prozedur im server-Explorer, und wählen Sie Ausführen aus. Dadurch wird die gespeicherte Prozedur ausgeführt und ihre Ergebnisse im Ausgabefenster angezeigt (siehe Abbildung 9).

Die Ergebnisse der gespeicherten Prozeduren werden im Ausgabefenster angezeigt.

Abbildung 9: Die Ergebnisse der gespeicherten Prozeduren werden im Ausgabefenster angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 3: Aktualisieren der DataTable-Spalten

An diesem Punkt gibt die Employees_Select gespeicherte Prozedur Werte und ManagerLastName zurückManagerFirstName, aber in EmployeesDataTable fehlen diese Spalten. Diese fehlenden Spalten können der DataTable auf zwei Arten hinzugefügt werden:

  • Manuell: Klicken Sie im DataSet-Designer mit der rechten Maustaste auf die DataTable, und wählen Sie im Menü Hinzufügen die Option Spalte aus. Anschließend können Sie die Spalte benennen und ihre Eigenschaften entsprechend festlegen.
  • Automatisch : Der TableAdapter-Konfigurations-Assistent aktualisiert die Spalten der DataTable so, dass sie die von der SelectCommand gespeicherten Prozedur zurückgegebenen Felder widerspiegeln. Bei Verwendung von AD-hoc-SQL-Anweisungen entfernt der Assistent auch die InsertCommandEigenschaften , UpdateCommandund DeleteCommand , da jetzt enthält SelectCommandJOIN. Wenn Sie gespeicherte Prozeduren verwenden, bleiben diese Befehlseigenschaften jedoch intakt.

In den vorherigen Tutorials haben wir das manuelle Hinzufügen von DataTable-Spalten untersucht, einschließlich Master/Detail using a Bulleted List of Master Records with a Details DataList and Uploading Files. Für dieses Tutorial verwenden wir jedoch den automatischen Ansatz über den TableAdapter-Konfigurations-Assistenten.

Klicken Sie zunächst mit der rechten Maustaste auf das EmployeesTableAdapter - und wählen Sie konfigurieren im Kontextmenü aus. Dadurch wird der TableAdapter-Konfigurations-Assistent geöffnet, der die gespeicherten Prozeduren zum Auswählen, Einfügen, Aktualisieren und Löschen zusammen mit ihren Rückgabewerten und Parametern (falls vorhanden) auflistet. Abbildung 10 zeigt diesen Assistenten. Hier sehen Wir, dass die Employees_Select gespeicherte Prozedur jetzt die ManagerFirstName Felder und ManagerLastName zurückgibt.

Der Assistent zeigt die Liste der aktualisierten Spalten für die gespeicherte Employees_Select Prozedur an.

Abbildung 10: Der Assistent zeigt die aktualisierte Spaltenliste für die Employees_Select gespeicherte Prozedur (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schließen Sie den Assistenten ab, indem Sie auf Fertig stellen klicken. Nach der Rückkehr zum DataSet-Designer enthält zwei EmployeesDataTable zusätzliche Spalten: ManagerFirstName und ManagerLastName.

Die EmployeesDataTable enthält zwei neue Spalten.

Abbildung 11: Enthält EmployeesDataTable zwei neue Spalten (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Um zu veranschaulichen, dass die aktualisierte Employees_Select gespeicherte Prozedur wirksam ist und dass die Einfüge-, Aktualisierungs- und Löschfunktionen des TableAdapters weiterhin funktionsfähig sind, erstellen wir eine Webseite, mit der Benutzer Mitarbeiter anzeigen und löschen können. Bevor wir eine solche Seite erstellen, müssen wir jedoch zunächst eine neue Klasse in der Geschäftslogikebene für die Arbeit mit Mitarbeitern aus dem NorthwindWithSprocs DataSet erstellen. In Schritt 4 erstellen wir eine EmployeesBLLWithSprocs Klasse. In Schritt 5 verwenden wir diese Klasse von einer ASP.NET Seite.

Schritt 4: Implementieren der Geschäftslogikebene

Erstellen Sie eine neue Klassendatei im Ordner mit dem ~/App_Code/BLL Namen EmployeesBLLWithSprocs.cs. Diese Klasse imitiert die Semantik der vorhandenen EmployeesBLL Klasse. Nur diese neue Klasse bietet weniger Methoden und verwendet das NorthwindWithSprocs DataSet (anstelle des Northwind DataSet). Fügen Sie der EmployeesBLLWithSprocs -Klasse den folgenden Code hinzu.

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

Die EmployeesBLLWithSprocs Eigenschaft der Klasse gibt Adapter einen instance des NorthwindWithSprocs DataSets zurückEmployeesTableAdapter. Dies wird von den Methoden der Klasse s GetEmployees und DeleteEmployee verwendet. Die GetEmployees -Methode ruft die EmployeesTableAdapter entsprechende GetEmployees s-Methode auf, die die Employees_Select gespeicherte Prozedur aufruft und ihre Ergebnisse in einem EmployeeDataTableauffüllt. Die DeleteEmployee -Methode ruft auf ähnliche Weise die s-Methode EmployeesTableAdapterDelete auf, die die Employees_Delete gespeicherte Prozedur aufruft.

Schritt 5: Arbeiten mit den Daten auf der Präsentationsebene

Nach Abschluss des EmployeesBLLWithSprocs Kurses sind wir bereit, mit Mitarbeiterdaten über eine ASP.NET Seite zu arbeiten. Öffnen Sie die JOINs.aspx Seite im AdvancedDAL Ordner, und ziehen Sie ein GridView-Objekt aus der Toolbox auf die Designer, und legen Sie die ID -Eigenschaft auf festEmployees. Binden Sie als Nächstes über das Smarttag von GridView das Raster an ein neues ObjectDataSource-Steuerelement namens EmployeesDataSource.

Konfigurieren Sie objectDataSource für die Verwendung der EmployeesBLLWithSprocs -Klasse, und stellen Sie auf den Registerkarten SELECT und DELETE sicher, dass die GetEmployees Methoden und DeleteEmployee aus den Dropdownlisten ausgewählt sind. Klicken Sie auf Fertig stellen, um die Konfiguration von ObjectDataSource abzuschließen.

Konfigurieren der ObjectDataSource für die Verwendung der EmployeesBLLWithSprocs-Klasse

Abbildung 12: Konfigurieren der ObjectDataSource für die Verwendung der EmployeesBLLWithSprocs -Klasse (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Lassen Sie die ObjectDataSource die GetEmployees- und DeleteEmployee-Methoden verwenden.

Abbildung 13: Verwenden der ObjectDataSource-Methode und DeleteEmployee der GetEmployees -Methode (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Visual Studio fügt der GridView für jede s-Spalte EmployeesDataTable ein BoundField hinzu. Entfernen Sie alle diese BoundFields mit Ausnahme Titlevon , LastName, FirstName, ManagerFirstNameund ManagerLastName benennen Sie die HeaderText Eigenschaften für die letzten vier BoundFields in Nachname, Vorname, Vorname des Managers bzw. Nachname des Managers um.

Damit Benutzer Mitarbeiter von dieser Seite löschen können, müssen wir zwei Dinge tun. Weisen Sie zunächst gridView an, Löschfunktionen bereitzustellen, indem Sie die Option Löschen aktivieren über das Smarttag aktivieren. Ändern Sie anschließend die ObjectDataSource-Eigenschaft OldValuesParameterFormatString von dem Wert, der vom ObjectDataSource-Assistenten (original_{0}) festgelegt wurde, in den Standardwert ({0}). Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup von GridView und ObjectDataSource wie folgt aussehen:

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

Testen Sie die Seite, indem Sie sie über einen Browser aufrufen. Wie abbildung 14 zeigt, werden auf der Seite jeder Mitarbeiter und sein Vorgesetzter (vorausgesetzt, er hat einen) aufgelistet.

Join im Employees_Select Gespeicherte Prozedur gibt den Namen des Managers zurück.

Abbildung 14: Gibt JOIN in der gespeicherten Employees_Select Prozedur den Namen des Managers zurück (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Durch Klicken auf die Schaltfläche Löschen wird der Löschworkflow gestartet, der in der Ausführung der Employees_Delete gespeicherten Prozedur gipfelt. Die versuchte Anweisung in der gespeicherten Prozedur schlägt DELETE jedoch aufgrund einer Verletzung der Fremdschlüsseleinschränkung fehl (siehe Abbildung 15). Insbesondere verfügt jeder Mitarbeiter über einen oder mehrere Datensätze in der Orders Tabelle, was dazu führt, dass der Löschvorgang fehlschlägt.

Das Löschen eines Mitarbeiters mit entsprechenden Aufträgen führt zu einer Verletzung der Fremdschlüsseleinschränkung

Abbildung 15: Löschen eines Mitarbeiters mit entsprechenden Aufträgen führt zu einer Verletzung der Fremdschlüsseleinschränkung (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Um das Löschen eines Mitarbeiters zuzulassen, haben Sie folgende Aktionen:

Ich belasse dies als Übung für den Leser.

Zusammenfassung

Bei der Arbeit mit relationalen Datenbanken ist es üblich, dass Abfragen ihre Daten aus mehreren verknüpften Tabellen abrufen. Korrelierte Unterabfragen und JOIN s bieten zwei verschiedene Techniken für den Zugriff auf Daten aus verknüpften Tabellen in einer Abfrage. In den vorherigen Tutorials haben wir am häufigsten korrelierte Unterabfragen verwendet, da der TableAdapter keine automatischen , UPDATE, und DELETE -Anweisungen für Abfragen mit JOIN s generieren INSERTkann. Diese Werte können zwar manuell bereitgestellt werden, aber bei Verwendung von AD-hoc-SQL-Anweisungen werden alle Anpassungen überschrieben, wenn der TableAdapter-Konfigurations-Assistent abgeschlossen ist.

Glücklicherweise leiden TableAdapters, die mit gespeicherten Prozeduren erstellt wurden, nicht unter derselben Sprödigkeit wie diejenigen, die mithilfe von Ad-hoc-SQL-Anweisungen erstellt wurden. Daher ist es möglich, einen TableAdapter zu erstellen, dessen Standard Abfrage bei Verwendung gespeicherter Prozeduren einen JOIN verwendet. In diesem Tutorial haben wir erfahren, wie Sie einen solchen TableAdapter erstellen. Wir haben zunächst eine JOIN-less-Abfrage SELECT für die TableAdapter-Standard-Abfrage verwendet, damit die entsprechenden gespeicherten Prozeduren zum Einfügen, Aktualisieren und Löschen automatisch erstellt werden. Nachdem die Anfänglichkonfiguration des TableAdapter abgeschlossen ist, haben wir die SelectCommand gespeicherte Prozedur erweitert, um eine JOIN zu verwenden, und den TableAdapter-Konfigurations-Assistenten erneut ausgeführt, um die EmployeesDataTable s-Spalten zu aktualisieren.

Durch erneutes Ausführen des TableAdapter-Konfigurations-Assistenten wurden die EmployeesDataTable Spalten automatisch aktualisiert, um die von der Employees_Select gespeicherten Prozedur zurückgegebenen Datenfelder widerzuspiegeln. Alternativ hätten wir diese Spalten manuell zur DataTable hinzufügen können. Im nächsten Tutorial wird das manuelle Hinzufügen von Spalten zur DataTable erläutert.

Viel Spaß beim Programmieren!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderen Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Gutachter für dieses Tutorial waren Hilton Geisenow, David Suru und Teresa Murphy. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.