Aktualisieren des TableAdapter-Steuerelements für die Verwendung von Verknüpfungen (VB)
von Scott Mitchell
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 JOIN
s 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 INSERT
Anweisungen , UPDATE
und 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 InsertCommand
Eigenschaften , UpdateCommand
und 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 INSERT
Anweisungen , UPDATE
und 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
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 INSERT
der 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 INSERT
Anweisungen , UPDATE
und DELETE
nicht erstellen, da die Standard Abfrage einen JOIN
enthält.
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 CategoryName
SupplierName
ein, wie in Abbildung 3 dargestellt.
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 InsertCommand
Eigenschaften , UpdateCommand
und 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 InsertCommand
Eigenschaften , UpdateCommand
und DeleteCommand
auf (Keine) festgelegt sind.
Abbildung 4: Die InsertCommand
Eigenschaften , UpdateCommand
und 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 InsertCommand
Eigenschaften , UpdateCommand
und 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 INSERT
Anweisungen , UPDATE
und 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 INSERT
Anweisungen , UPDATE
und 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 SelectCommand
gespeicherten Prozeduren , InsertCommand
, UpdateCommand
oder 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 JOIN
erreicht 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 JOIN
abzurufen.
Ö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 .
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 INSERT
Anweisungen , UPDATE
und 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_Update
und Employees_Delete
, wie in Abbildung 6 dargestellt.
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.
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_Update
und 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 InsertCommand
Eigenschaften , UpdateCommand
und DeleteCommand
ordnungsgemäß konfiguriert sind, um die entsprechenden gespeicherten Prozeduren aufzurufen.
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 InsertCommand
Eigenschaften , UpdateCommand
und 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_Select
auswä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).
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 dieInsertCommand
Eigenschaften ,UpdateCommand
undDeleteCommand
, da dieSelectCommand
jetzt eineJOIN
enthä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.
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
.
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 EmployeesTableAdapter
zurü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 EmployeeDataTable
auffü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.
Abbildung 12: Konfigurieren der ObjectDataSource für die Verwendung der EmployeesBLLWithSprocs
-Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
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 Title
von , LastName
, FirstName
, ManagerFirstName
und 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).
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.
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 derOrders
Tabelle zu löschen, bevor Sie denEmployees
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 , UPDATE
und DELETE
-Anweisungen für Abfragen generieren INSERT
kann, 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.