Aktualisieren des TableAdapter-Steuerelements für die Verwendung von Verknüpfungen (C#)
von Scott Mitchell
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 JOIN
s 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
, , UPDATE
und 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 InsertCommand
Eigenschaften , UpdateCommand
und 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 INSERT
Anweisungen , UPDATE
und 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
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 INSERT
tableAdapter automatisch , , UPDATE
und 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 INSERT
Anweisungen , UPDATE
und DELETE
nicht erstellen, da die Standard Abfrage einen JOIN
enthält.
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 SupplierName
ein, wie Abbildung 3 zeigt.
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 InsertCommand
Eigenschaften , 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 InsertCommand
Eigenschaften , UpdateCommand
und DeleteCommand
auf (None) festgelegt sind.
Abbildung 4: Die InsertCommand
Eigenschaften , UpdateCommand
und 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 InsertCommand
Eigenschaften , UpdateCommand
und 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 INSERT
Anweisungen , UPDATE
und 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
, UPDATE
und 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 SelectCommand
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
, 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 JOIN
erreicht 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 JOIN
abzurufen.
Ö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 .
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 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.
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
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 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 zum Einfügen, Aktualisieren und Löschen automatisch erstellt wurden und die InsertCommand
Eigenschaften , UpdateCommand
und 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_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 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).
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 dieInsertCommand
Eigenschaften ,UpdateCommand
undDeleteCommand
, da jetzt enthältSelectCommand
JOIN
. 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.
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
.
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 EmployeeDataTable
auffüllt. Die DeleteEmployee
-Methode ruft auf ähnliche Weise die s-Methode EmployeesTableAdapter
Delete
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.
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: 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 Title
von , LastName
, FirstName
, ManagerFirstName
und 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.
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.
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:
- Aktualisieren Sie die Fremdschlüsseleinschränkung, um Löschvorgänge zu kaskadieren.
- 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 (Verwenden vorhandener gespeicherter Prozeduren für typisierte DataSets ) 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 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 INSERT
kann. 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.