Freigeben über


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

von Scott Mitchell

PDF herunterladen

Bei der Arbeit mit einer Datenbank ist es üblich, 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 sie sehen, wie Sie einen TableAdapter erstellen, der einen JOIN in die Standard Abfrage einschließt.

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 Kategorien und Lieferantennamen jedes Produkts auflisten. Die Products Tabelle verfügt über CategoryID - und SupplierID -Werte, aber die tatsächlichen Kategorie- und Lieferantennamen befinden sich in den Categories Tabellen und Suppliers .

Um Informationen aus einer anderen verknüpften 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. Im Tutorial Erstellen einer Datenzugriffsebene haben wir beispielsweise zwei korrelierte Unterabfragen in der ProductsTableAdapter Abfrage s Standard verwendet, um die Kategorie- und Lieferantennamen für jedes Produkt zurückzugeben. Ein JOIN ist ein SQL-Konstrukt, das verwandte Zeilen aus zwei verschiedenen Tabellen zusammenführt. Wir haben eine im Tutorial Abfragen von Daten mit dem SqlDataSource-Steuerelement verwendetJOIN, um Kategorieinformationen zusammen mit jedem Produkt anzuzeigen.

Der Grund, warum wir auf die Verwendung JOIN von s mit den TableAdapters verzichtet haben, liegt an den Einschränkungen im TableAdapter-Assistenten, um die entsprechenden INSERTAnweisungen , UPDATEund DELETE automatisch zu generieren. Genauer gesagt: Wenn die TableAdapter-Standard Abfrage s s enthältJOIN, kann tableAdapter die Ad-hoc-SQL-Anweisungen oder gespeicherten Prozeduren für die InsertCommandEigenschaften , UpdateCommandund DeleteCommand nicht automatisch erstellen.

In diesem Tutorial werden wir kurz korrelierte Unterabfragen und -abfragen vergleichen und JOIN vergleichen, bevor wir untersuchen, wie ein TableAdapter erstellt wird, der s in die Standard Abfrage einschließtJOIN.

Vergleichen und Kontrastieren korrelierter Unterabfragen undJOIN s

Denken Sie daran, dass die ProductsTableAdapter im ersten Tutorial im Northwind DataSet erstellte Unterabfragen korrelierte Unterabfragen verwendet, um die entsprechende Kategorie und den Lieferantennamen jedes Produkts zurückzubringen. Die ProductsTableAdapter s-Standard-Abfrage 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 anstelle von Unterabfragen 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

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

Hinweis

JOIN 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 zu 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, lassen viele Entwickler sich 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 werden. Ihr Rat besteht also darin, 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 Ratschläges sofort ihre Präferenz gegenüber JOIN korrelierten Unterabfragen ausdrücken.

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 generiert diese Anweisungen automatisch, 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 die Verwendung von 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 hier, um das Bild in voller Größe anzuzeigen)

Standardmäßig erstellt INSERTder TableAdapter die Anweisungen , UPDATE, und DELETE 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 des Fensters

Abbildung 2: Eingeben einer Hauptabfrage, 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 und CategoryNameSupplierNameein, wie in Abbildung 3 dargestellt.

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, sind dem TableAdapter keine Werte für die InsertCommandEigenschaften , UpdateCommandund DeleteCommand vorhanden. Um dies zu bestätigen, klicken Sie im Designer auf den TableAdapter, und wechseln Sie dann zum Eigenschaftenfenster. Dort sehen Sie, dass die InsertCommandEigenschaften , UpdateCommandund DeleteCommand auf (Keine) festgelegt sind.

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

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

Um dieses Manko 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-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 dann die TableAdapter s SelectCommand aus dem Eigenschaftenfenster manuell 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 INSERTAnweisungen , UPDATEund DELETE jedes Mal, wenn die TableAdapter-Standard Abfrage über den Assistenten neu konfiguriert wird, neu erstellt werden. 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 Sprödheit 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 SelectCommandgespeicherten Prozeduren , 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 , sodass ein JOIN verwendet wird, das zusätzliche Spalten aus verknüpften Tabellen zurückgibt. Schließlich 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. Die Mitarbeiterin Anne Dodsworth hat beispielsweise den ReportTo Wert 5, d. h. der EmployeeID von Steven Buchanan. Folglich berichtet Anne an Steven, ihren Manager. Neben der Meldung des Werts jedes Mitarbeiters ReportsTo möchten wir möglicherweise auch den Namen des Vorgesetzten abrufen. Dies kann mithilfe von JOINerreicht werden. Die Verwendung von beim JOIN anfänglichen Erstellen des TableAdapter verhindert jedoch, dass der Assistent automatisch die entsprechenden Einfüge-, Aktualisierungs- 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 gespeicherte Standard 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 die 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 Auffrischung zum Erstellen neuer gespeicherter Prozeduren aus dem TableAdapter-Assistenten finden Sie im Tutorial Erstellen neuer gespeicherter Prozeduren für das Typisierte DataSet s TableAdapters .

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 Prozeduren von TableAdapter.

Abbildung 6: Benennen der 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. Stellen Sie außerdem sicher, dass das Kontrollkästchen Create methods to send updates direct to the database (GenerateDBDirectMethods) (Methoden zum direkten Senden von Updates an die Datenbank (GenerateDBDirectMethods) aktiviert ist.

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 gerade erstellte und EmployeesTableAdapter . Die DataTable enthält eine Spalte für jedes Feld, das von der Standard-Abfrage zurückgegeben wird. Klicken Sie auf den 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 enthält 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 "Einfügen", "Aktualisieren" und "Löschen" automatisch erstellt und die InsertCommandEigenschaften , UpdateCommandund DeleteCommand ordnungsgemäß konfiguriert wurden, können wir die SelectCommand gespeicherte Prozedur anpassen, um zusätzliche Informationen zu jedem Mitarbeiter-Vorgesetzten zurückzugeben. Insbesondere müssen wir die Employees_Select gespeicherte Prozedur aktualisieren, um eine JOIN zu verwenden und die Manager-Werte FirstName und LastName -Werte zurückzugeben. Nachdem die gespeicherte Prozedur aktualisiert wurde, müssen wir die DataTable aktualisieren, sodass sie diese zusätzlichen Spalten enthält. Diese beiden Aufgaben werden in Den Schritten 2 und 3 behandelt.

Schritt 2: Anpassen der gespeicherten Prozedur auf Einschließen einesJOIN

Wechseln Sie zunächst zum Server Explorer, suchen Sie einen Drilldown in den Ordner gespeicherte Prozeduren der Northwind-Datenbank, 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 Explorer Server, 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 gespeicherter 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 zurückManagerLastName, aber diese EmployeesDataTable Spalten ManagerFirstName fehlen. 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, um die von der SelectCommand gespeicherten Prozedur zurückgegebenen Felder widerzuspiegeln. Wenn Sie Ad-hoc-SQL-Anweisungen verwenden, entfernt der Assistent auch die InsertCommandEigenschaften , UpdateCommandund DeleteCommand , da die SelectCommand jetzt eine JOINenthält. Bei Verwendung gespeicherter Prozeduren bleiben diese Befehlseigenschaften jedoch intakt.

In 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. In unserem nächsten Tutorial werden wir diesen Prozess noch ausführlicher untersuchen. 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 auflistet, die zum Auswählen, Einfügen, Aktualisieren und Löschen verwendet werden, sowie deren Rückgabewerte und Parameter (falls vorhanden). Abbildung 10 zeigt diesen Assistenten. Hier sehen Wir, dass die Employees_Select gespeicherte Prozedur nun die ManagerFirstName Felder und ManagerLastName zurückgibt.

Der Assistent zeigt die aktualisierte Spaltenliste für die Employees_Select gespeicherten Prozedur an.

Abbildung 10: Der Assistent zeigt die aktualisierte Spaltenliste für die Employees_Select gespeicherte Prozedur (Klicken Sie, 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 die EmployeesDataTable zwei 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-, Update- 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 erstellen, um mit Mitarbeitern aus dem NorthwindWithSprocs DataSet zu arbeiten. In Schritt 4 erstellen wir eine EmployeesBLLWithSprocs Klasse. In Schritt 5 verwenden wir diese Klasse von einer ASP.NET Seite aus.

Schritt 4: Implementieren der Geschäftslogikebene

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

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

Die EmployeesBLLWithSprocs Eigenschaft der Klasse gibt Adapter einen instance des NorthwindWithSprocs DataSet s EmployeesTableAdapterzurück. Dies wird von der Klasse s GetEmployees und DeleteEmployee den Methoden 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 ebenfalls die EmployeesTableAdapter s-Methode Delete auf, die die Employees_Delete gespeicherte Prozedur aufruft.

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

Nach Abschluss der EmployeesBLLWithSprocs Klasse sind wir bereit, mit Mitarbeiterdaten über eine ASP.NET Seite zu arbeiten. Öffnen Sie die JOINs.aspx Seite im AdvancedDAL Ordner, und ziehen Sie eine GridView 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 mit dem Namen 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 Methoden GetEmployees und DeleteEmployee verwenden

Abbildung 13: Lassen Sie die ObjectDataSource-Methode GetEmployees und DeleteEmployee verwenden (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Visual Studio fügt der GridView für jede spalte ein EmployeesDataTable BoundField hinzu. Entfernen Sie alle diese BoundFields mit Ausnahme Titlevon , LastName, FirstName, ManagerFirstNameund ManagerLastName benennen Sie die Eigenschaften für die HeaderText 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 die GridView an, Löschfunktionen bereitzustellen, indem Sie die Option Löschen über das Smarttag aktivieren aktivieren. Ändern Sie anschließend die ObjectDataSource-Eigenschaft OldValuesParameterFormatString von dem wert, der vom ObjectDataSource-Assistenten (original_{0}) in den Standardwert ({0}) festgelegt wurde. Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup Ihres GridView- und ObjectDataSource-Markups 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 besuchen. Wie Abbildung 14 zeigt, listet die Seite jeden Mitarbeiter und seinen Vorgesetzten auf (vorausgesetzt, er hat einen).

Der JOIN in der Employees_Select Gespeicherten Prozedur gibt den Namen des Managers zurück.

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

Wenn Sie auf die Schaltfläche Löschen klicken, wird der Löschworkflow gestartet, der in der Ausführung der Employees_Delete gespeicherten Prozedur gipfelt. Die versuchte Anweisung in der gespeicherten DELETE Prozedur schlägt 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, wodurch das Löschen fehlschlägt.

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

Abbildung 15: Löschen eines Mitarbeiters mit entsprechenden Bestellungen 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, können Sie Folgendes ausführen:

  • Aktualisieren Sie die Fremdschlüsseleinschränkung auf kaskadierende Löschvorgänge.
  • Löschen Sie die Datensätze manuell aus der Orders Tabelle für die Mitarbeiter, die Sie löschen möchten, oder
  • Aktualisieren Sie die Employees_Delete gespeicherte Prozedur, um zuerst die zugehörigen Datensätze aus der Orders Tabelle zu löschen, bevor Sie den Employees Datensatz löschen. Dieses Verfahren wurde im Tutorial Using Existing Stored Procedures for the Typed DataSet s TableAdapters erläutert.

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 verwandten Tabellen in einer Abfrage. In früheren Tutorials haben wir am häufigsten korrelierte Unterabfragen verwendet, da der TableAdapter nicht automatisch , UPDATEund DELETE -Anweisungen für Abfragen generieren INSERTkann, die s betreffenJOIN. 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 der gleichen Sprödigkeit wie die mit Ad-hoc-SQL-Anweisungen erstellten. Daher ist es möglich, einen TableAdapter zu erstellen, dessen Standard Abfrage einen JOIN verwendet, wenn gespeicherte Prozeduren verwendet werden. 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, sodass die entsprechenden gespeicherten Prozeduren zum Einfügen, Aktualisieren und Löschen automatisch erstellt werden. Nach Abschluss der Ersten Konfiguration von TableAdapter 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 untersucht.

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.