Verwenden von vorhandenen gespeicherten Prozeduren für die TableAdapter-Steuerelemente des typisierten DataSet (C#)
von Scott Mitchell
Im vorherigen Tutorial haben wir gelernt, wie Sie den TableAdapter-Assistenten verwenden, um neue gespeicherte Prozeduren zu generieren. In diesem Tutorial erfahren Sie, wie derselbe TableAdapter-Assistent mit vorhandenen gespeicherten Prozeduren arbeiten kann. Außerdem erfahren Sie, wie Sie unserer Datenbank neue gespeicherte Prozeduren manuell hinzufügen.
Einführung
Im vorherigen Tutorial haben wir gezeigt, wie die TableAdapters des typisierten DataSets so konfiguriert werden können, dass gespeicherte Prozeduren für den Zugriff auf Daten anstelle von Ad-hoc-SQL-Anweisungen verwendet werden können. Insbesondere haben wir untersucht, wie der TableAdapter-Assistent diese gespeicherten Prozeduren automatisch erstellt. Beim Portieren einer Legacyanwendung auf ASP.NET 2.0 oder beim Erstellen einer ASP.NET 2.0-Website um ein vorhandenes Datenmodell besteht die Wahrscheinlichkeit, dass die Datenbank bereits die benötigten gespeicherten Prozeduren enthält. Alternativ können Sie Ihre gespeicherten Prozeduren lieber manuell oder mit einem anderen Tool als dem TableAdapter-Assistenten erstellen, der Ihre gespeicherten Prozeduren automatisch generiert.
In diesem Tutorial erfahren Sie, wie Sie den TableAdapter für die Verwendung vorhandener gespeicherter Prozeduren konfigurieren. Da die Northwind-Datenbank nur über einen kleinen Satz integrierter gespeicherter Prozeduren verfügt, werden wir uns auch die Schritte ansehen, die zum manuellen Hinzufügen neuer gespeicherter Prozeduren zur Datenbank über die Visual Studio-Umgebung erforderlich sind. Los geht's!
Hinweis
Im Tutorial Umschließen von Datenbankänderungen in einer Transaktion haben wir dem TableAdapter Methoden hinzugefügt, um Transaktionen (BeginTransaction
, CommitTransaction
usw.) zu unterstützen. Alternativ können Transaktionen vollständig in einer gespeicherten Prozedur verwaltet werden, die keine Änderungen am Code der Datenzugriffsebene erfordert. In diesem Tutorial untersuchen wir die T-SQL-Befehle, die zum Ausführen von Anweisungen einer gespeicherten Prozedur innerhalb des Bereichs einer Transaktion verwendet werden.
Schritt 1: Hinzufügen gespeicherter Prozeduren zur Northwind-Datenbank
Visual Studio vereinfacht das Hinzufügen neuer gespeicherter Prozeduren zu einer Datenbank. Fügen Sie der Northwind-Datenbank eine neue gespeicherte Prozedur hinzu, die alle Spalten aus der Products
Tabelle für diejenigen zurückgibt, die einen bestimmten CategoryID
Wert haben. Erweitern Sie im Fenster Server Explorer die Northwind-Datenbank, sodass ihre Ordner – Datenbankdiagramme, Tabellen, Ansichten usw. – angezeigt werden. Wie im vorherigen Tutorial gezeigt, enthält der Ordner Gespeicherte Prozeduren die vorhandenen gespeicherten Prozeduren der Datenbank. Um eine neue gespeicherte Prozedur hinzuzufügen, klicken Sie einfach mit der rechten Maustaste auf den Ordner Gespeicherte Prozeduren, und wählen Sie im Kontextmenü die Option Neue gespeicherte Prozedur hinzufügen aus.
Abbildung 1: Right-Click des Ordners Gespeicherte Prozeduren und Hinzufügen einer neuen gespeicherten Prozedur (Klicken Sie hier, um das vollständige Bild anzuzeigen)
Wie Abbildung 1 zeigt, wird durch Auswählen der Option Neue gespeicherte Prozedur hinzufügen ein Skriptfenster in Visual Studio mit der Gliederung des SQL-Skripts geöffnet, das zum Erstellen der gespeicherten Prozedur erforderlich ist. Es ist unsere Aufgabe, dieses Skript zu erstellen und auszuführen, an dem die gespeicherte Prozedur der Datenbank hinzugefügt wird.
Geben Sie das folgende Skript ein:
CREATE PROCEDURE dbo.Products_SelectByCategoryID
(
@CategoryID int
)
AS
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued
FROM Products
WHERE CategoryID = @CategoryID
Dieses Skript fügt der Northwind-Datenbank bei Ausführung eine neue gespeicherte Prozedur mit dem Namen Products_SelectByCategoryID
hinzu. Diese gespeicherte Prozedur akzeptiert einen einzelnen Eingabeparameter (@CategoryID
vom Typ int
) und gibt alle Felder für diese Produkte mit einem übereinstimmenden CategoryID
Wert zurück.
Um dieses CREATE PROCEDURE
Skript auszuführen und die gespeicherte Prozedur der Datenbank hinzuzufügen, klicken Sie auf der Symbolleiste auf das Symbol Speichern, oder drücken Sie STRG+S. Danach wird der Ordner Gespeicherte Prozeduren aktualisiert und zeigt die neu erstellte gespeicherte Prozedur an. Außerdem ändert sich das Skript im Fenster subtil von CREATE PROCEDURE dbo.Products_SelectProductByCategoryID
in ALTER PROCEDURE
dbo.Products_SelectProductByCategoryID
. CREATE PROCEDURE
fügt der Datenbank eine neue gespeicherte Prozedur hinzu, während ALTER PROCEDURE
eine vorhandene aktualisiert wird. Da sich der Start des Skripts in ALTER PROCEDURE
geändert hat, wird die gespeicherte Prozedur durch Ändern der Eingabeparameter oder SQL-Anweisungen und durch Klicken auf das Symbol Speichern die gespeicherte Prozedur mit diesen Änderungen aktualisiert.
Abbildung 2 zeigt Visual Studio nach dem Speichern der Products_SelectByCategoryID
gespeicherten Prozedur.
Abbildung 2: Die gespeicherte Prozedur Products_SelectByCategoryID
wurde der Datenbank hinzugefügt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Schritt 2: Konfigurieren des TableAdapters für die Verwendung einer vorhandenen gespeicherten Prozedur
Nachdem die Products_SelectByCategoryID
gespeicherte Prozedur der Datenbank hinzugefügt wurde, können wir unsere Datenzugriffsebene so konfigurieren, dass diese gespeicherte Prozedur verwendet wird, wenn eine ihrer Methoden aufgerufen wird. Insbesondere fügen wir dem ProductsTableAdapter
im Typisierten DataSet eine GetProductsByCategoryID(categoryID)
Methode hinzu, die NorthwindWithSprocs
die Products_SelectByCategoryID
soeben erstellte gespeicherte Prozedur aufruft.
Öffnen Sie zunächst das NorthwindWithSprocs
DataSet. Klicken Sie mit der rechten Maustaste auf das ProductsTableAdapter
, und wählen Sie Abfrage hinzufügen aus, um den TableAdapter-Abfragekonfigurations-Assistenten zu starten. Im vorherigen Tutorial haben wir uns dafür entschieden, dass der TableAdapter eine neue gespeicherte Prozedur für uns erstellt. Für dieses Tutorial möchten wir jedoch die neue TableAdapter-Methode mit der vorhandenen Products_SelectByCategoryID
gespeicherten Prozedur verknüpfen. Wählen Sie daher im ersten Schritt des Assistenten die Option Vorhandene gespeicherte Prozedur verwenden aus, und klicken Sie dann auf Weiter.
Abbildung 3: Auswählen der Option Vorhandene gespeicherte Prozedur verwenden (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Der folgende Bildschirm enthält eine Dropdownliste mit den gespeicherten Prozeduren der Datenbank. Wenn Sie eine gespeicherte Prozedur auswählen, werden die Eingabeparameter links und die (falls vorhanden) zurückgegebenen Datenfelder auf der rechten Seite aufgelistet. Wählen Sie die gespeicherte Products_SelectByCategoryID
Prozedur aus der Liste aus, und klicken Sie auf Weiter.
Abbildung 4: Auswählen der gespeicherten Products_SelectByCategoryID
Prozedur (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Im nächsten Bildschirm werden wir gefragt, welche Art von Daten von der gespeicherten Prozedur zurückgegeben wird, und unsere Antwort bestimmt den Typ, der von der TableAdapter s-Methode zurückgegeben wird. Wenn wir beispielsweise angeben, dass tabellarische Daten zurückgegeben werden, gibt die Methode eine ProductsDataTable
instance aufgefüllt mit den datensätzen, die von der gespeicherten Prozedur zurückgegeben werden. Wenn wir hingegen angeben, dass diese gespeicherte Prozedur einen einzelnen Wert zurückgibt, gibt der TableAdapter einen object
zurück, dem der Wert in der ersten Spalte des ersten Datensatzes zugewiesen ist, der von der gespeicherten Prozedur zurückgegeben wird.
Da die Products_SelectByCategoryID
gespeicherte Prozedur alle Produkte zurückgibt, die zu einer bestimmten Kategorie gehören, wählen Sie die erste Antwort aus – Tabellarische Daten – und klicken Sie auf Weiter.
Abbildung 5: Angeben, dass die gespeicherte Prozedur tabellarische Daten zurückgibt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Es bleibt nur noch anzugeben, welche Methodenmuster verwendet werden sollen, gefolgt von den Namen für diese Methoden. Lassen Sie sowohl die Optionen DataTable ausfüllen als auch Zurückgeben einer DataTable aktiviert, benennen Sie die Methoden jedoch in und GetProductsByCategoryID
umFillByCategoryID
. Klicken Sie dann auf Weiter, um eine Zusammenfassung der Aufgaben zu überprüfen, die der Assistent ausführt. Wenn alles richtig aussieht, klicken Sie auf Fertig stellen.
Abbildung 6: Benennen Sie die Methoden FillByCategoryID
und GetProductsByCategoryID
(Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Hinweis
Die soeben erstellten FillByCategoryID
TableAdapter-Methoden und GetProductsByCategoryID
erwarten einen Eingabeparameter vom Typ int
. Dieser Eingabeparameterwert wird über @CategoryID
ihren Parameter an die gespeicherte Prozedur übergeben. Wenn Sie die Parameter der Products_SelectByCategory
gespeicherten Prozedur ändern, müssen Sie auch die Parameter für diese TableAdapter-Methoden aktualisieren. Wie im vorherigen Tutorial erläutert, kann dies auf zwei Arten erfolgen: durch manuelles Hinzufügen oder Entfernen von Parametern aus der Parameterauflistung oder durch erneutes Ausführen des TableAdapter-Assistenten.
Schritt 3: Hinzufügen einerGetProductsByCategoryID(categoryID)
Methode zur BLL
Nach Abschluss der GetProductsByCategoryID
DAL-Methode besteht der nächste Schritt darin, den Zugriff auf diese Methode in der Geschäftslogikebene zu ermöglichen. Öffnen Sie die ProductsBLLWithSprocs
Klassendatei, und fügen Sie die folgende Methode hinzu:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public NorthwindWithSprocs.ProductsDataTable GetProductByCategoryID(int categoryID)
{
return Adapter.GetProductsByCategoryID(categoryID);
}
Diese BLL-Methode gibt einfach das ProductsDataTable
von der s-Methode ProductsTableAdapter
GetProductsByCategoryID
zurückgegebene zurück. Das DataObjectMethodAttribute
Attribut stellt Metadaten bereit, die vom Assistenten "Datenquelle konfigurieren" von ObjectDataSource verwendet werden. Insbesondere wird diese Methode in der Dropdownliste der Registerkarte SELECT angezeigt.
Schritt 4: Anzeigen von Produkten nach Kategorie
Um die neu hinzugefügte Products_SelectByCategoryID
gespeicherte Prozedur und die entsprechenden DAL- und BLL-Methoden zu testen, erstellen Sie eine ASP.NET Seite, die eine DropDownList und eine GridView enthält. Die DropDownList listet alle Kategorien in der Datenbank auf, während die GridView die Produkte anzeigt, die zur ausgewählten Kategorie gehören.
Hinweis
In vorherigen Tutorials haben wir master-/Detailschnittstellen mithilfe von DropDownLists erstellt. Einen ausführlicheren Einblick in die Implementierung eines solchen master/Detailberichts finden Sie im Tutorial Master-/Detailfilterung mit einer DropDownList.
Öffnen Sie die ExistingSprocs.aspx
Seite im AdvancedDAL
Ordner, und ziehen Sie eine DropDownList aus der Toolbox auf die Designer. Legen Sie die DropDownList-Eigenschaft ID
auf Categories
und ihre AutoPostBack
Eigenschaft auf true
fest. Binden Sie als Nächstes über das Smarttag die DropDownList an eine neue ObjectDataSource mit dem Namen CategoriesDataSource
. Konfigurieren Sie die ObjectDataSource so, dass sie ihre Daten aus der S-Methode der CategoriesBLL
Klasse GetCategories
abruft. Legen Sie die Dropdownlisten in den Registerkarten UPDATE, INSERT und DELETE auf (Keine) fest.
Abbildung 7: Abrufen von Daten aus der Methode der CategoriesBLL
Klasse (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)GetCategories
Abbildung 8: Legen Sie die Drop-Down Listen in den Registerkarten UPDATE, INSERT und DELETE auf (Keine) fest (Klicken Sie, um das bild in voller Größe anzuzeigen)
Nachdem Sie den ObjectDataSource-Assistenten abgeschlossen haben, konfigurieren Sie die DropDownList so, dass das CategoryName
Datenfeld angezeigt und das CategoryID
Feld als für jeden Value
ListItem
verwendet wird.
An diesem Punkt sollte das deklarative Markup von DropDownList und ObjectDataSource wie folgt aussehen:
<asp:DropDownList ID="Categories" runat="server" AutoPostBack="True"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID">
</asp:DropDownList>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
Ziehen Sie als Nächstes eine GridView auf die Designer, und platzieren Sie sie unter der DropDownList. Legen Sie die GridView s ID
auf ProductsByCategory
fest, und binden Sie sie über das Smarttag an eine neue ObjectDataSource mit dem Namen ProductsByCategoryDataSource
. Konfigurieren Sie die ProductsByCategoryDataSource
ObjectDataSource so, dass sie die ProductsBLLWithSprocs
-Klasse verwendet, damit sie ihre Daten mithilfe der GetProductsByCategoryID(categoryID)
-Methode abruft. Da diese GridView nur zum Anzeigen von Daten verwendet wird, legen Sie die Dropdownlisten in den Registerkarten UPDATE, INSERT und DELETE auf (Keine) fest, und klicken Sie auf Weiter.
Abbildung 9: Konfigurieren der ObjectDataSource für die Verwendung der ProductsBLLWithSprocs
-Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Abbildung 10: Abrufen von Daten aus der GetProductsByCategoryID(categoryID)
Methode (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Die auf der Registerkarte SELECT ausgewählte Methode erwartet einen Parameter, sodass wir im letzten Schritt des Assistenten zur Eingabe der Quelle des Parameters aufgefordert werden. Legen Sie die Dropdownliste Parameterquelle auf Steuerelement fest, und wählen Sie das Categories
Steuerelement aus der Dropdownliste ControlID aus. Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.
Abbildung 11: Verwenden Sie die Categories
DropDownList als Quelle des categoryID
Parameters (Klicken Sie, um das bild in voller Größe anzuzeigen)
Nach Abschluss des ObjectDataSource-Assistenten fügt Visual Studio BoundFields und ein CheckBoxField für jedes Produktdatenfeld hinzu. Sie können diese Felder so anpassen, wie Sie es für richtig halten.
Besuchen Sie die Seite über einen Browser. Beim Besuch der Seite wird die Kategorie Getränke ausgewählt und die entsprechenden Produkte im Raster aufgeführt. Das Ändern der Dropdownliste in eine alternative Kategorie, wie Abbildung 12 zeigt, führt zu einem Postback und lädt das Raster mit den Produkten der neu ausgewählten Kategorie neu.
Abbildung 12: Die Produkte in der Kategorie "Produktion" werden angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Schritt 5: Umschließen von Anweisungen einer gespeicherten Prozedur innerhalb des Bereichs einer Transaktion
Im Tutorial Umschließen von Datenbankänderungen in einer Transaktion haben wir Techniken zum Ausführen einer Reihe von Datenbankänderungsanweisungen innerhalb des Bereichs einer Transaktion erläutert. Erinnern Sie sich daran, dass die im Rahmen einer Transaktion durchgeführten Änderungen entweder alle erfolgreich oder alle fehlschlagen, was die Atomität garantiert. Zu den Techniken für die Verwendung von Transaktionen gehören:
- Verwenden der Klassen im
System.Transactions
Namespace, - Wenn die Datenzugriffsebene ADO.NET Klassen wie
SqlTransaction
und verwendet - Hinzufügen der T-SQL-Transaktionsbefehle direkt in der gespeicherten Prozedur
Im Tutorial Umbruch von Datenbankänderungen in einer Transaktion wurden die ADO.NET Klassen in der DAL verwendet. Im weiteren Verlauf dieses Tutorials wird untersucht, wie Sie eine Transaktion mithilfe von T-SQL-Befehlen innerhalb einer gespeicherten Prozedur verwalten.
Die drei wichtigen SQL-Befehle zum manuellen Starten, Commiten und Rollback einer Transaktion sind BEGIN TRANSACTION
, COMMIT TRANSACTION
bzw. .ROLLBACK TRANSACTION
Wie beim ADO.NET-Ansatz müssen wir bei der Verwendung von Transaktionen aus einer gespeicherten Prozedur das folgende Muster anwenden:
- Geben Sie den Beginn einer Transaktion an.
- Führen Sie die SQL-Anweisungen aus, die die Transaktion umfassen.
- Wenn in einer der Anweisungen aus Schritt 2 ein Fehler auftritt, führen Sie ein Rollback für die Transaktion aus.
- Wenn alle Anweisungen aus Schritt 2 ohne Fehler abgeschlossen sind, committen Sie die Transaktion.
Dieses Muster kann in der T-SQL-Syntax mithilfe der folgenden Vorlage implementiert werden:
BEGIN TRY
BEGIN TRANSACTION -- Start the transaction
... Perform the SQL statements that makeup the transaction ...
-- If we reach here, success!
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- Whoops, there was an error
ROLLBACK TRANSACTION
-- Raise an error with the
-- details of the exception
DECLARE @ErrMsg nvarchar(4000),
@ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
Die Vorlage definiert zunächst einen Block, ein TRY...CATCH
neues Konstrukt SQL Server 2005. Wie bei try...catch
Blöcken in C# führt der SQL-Block TRY...CATCH
die Anweisungen im TRY
Block aus. Wenn eine Anweisung einen Fehler auslöst, wird das Steuerelement sofort an den CATCH
Block übertragen.
Wenn bei der Ausführung der SQL-Anweisungen, die die Transaktion bilden, keine Fehler auftreten, werden die Änderungen von der COMMIT TRANSACTION
Anweisung committent und die Transaktion abgeschlossen. Wenn jedoch eine der Anweisungen zu einem Fehler führt, gibt die ROLLBACK TRANSACTION
im CATCH
Block die Datenbank in ihren Zustand vor Beginn der Transaktion zurück. Die gespeicherte Prozedur löst auch mithilfe des Befehls RAISERROR einen Fehler aus, der dazu führt, dass ein SqlException
in der Anwendung ausgelöst wird.
Hinweis
Da der TRY...CATCH
Block in SQL Server 2005 neu ist, funktioniert die obige Vorlage nicht, wenn Sie ältere Versionen von Microsoft SQL Server verwenden.
Sehen wir uns ein konkretes Beispiel an. Zwischen den Categories
Tabellen und Products
gibt es eine Fremdschlüsseleinschränkung, was bedeutet, dass jedes CategoryID
Feld in der Products
Tabelle einem CategoryID
Wert in der Categories
Tabelle zugeordnet werden muss. Jede Aktion, die gegen diese Einschränkung verstößt, z. B. der Versuch, eine Kategorie mit zugeordneten Produkten zu löschen, führt zu einer Verletzung der Fremdschlüsseleinschränkung. Um dies zu überprüfen, lesen Sie das Beispiel Aktualisieren und Löschen vorhandener Binärdaten im Abschnitt Arbeiten mit Binären Daten (~/BinaryData/UpdatingAndDeleting.aspx
) erneut. Diese Seite listet jede Kategorie im System zusammen mit den Schaltflächen Bearbeiten und Löschen auf (siehe Abbildung 13). Wenn Sie jedoch versuchen, eine Kategorie zu löschen, die produkte zugeordnet hat ( z. B. Getränke ), schlägt das Löschen aufgrund einer Verletzung der Fremdschlüsseleinschränkung fehl (siehe Abbildung 14).
Abbildung 13: Jede Kategorie wird in einer GridView mit Schaltflächen "Bearbeiten" und "Löschen" angezeigt (Zum Anzeigen des Bilds in voller Größe klicken)
Abbildung 14: Eine Kategorie mit vorhandenen Produkten kann nicht gelöscht werden (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Stellen Sie sich jedoch vor, wir möchten zulassen, dass Kategorien gelöscht werden können, unabhängig davon, ob sie über zugehörige Produkte verfügen. Wenn eine Kategorie mit Produkten gelöscht wird, stellen Sie sich vor, dass wir auch ihre vorhandenen Produkte löschen möchten (obwohl eine andere Möglichkeit wäre, einfach ihre Produktwerte CategoryID
auf festzulegen NULL
). Diese Funktionalität könnte durch die Kaskadenregeln der Fremdschlüsseleinschränkung implementiert werden. Alternativ können wir eine gespeicherte Prozedur erstellen, die einen @CategoryID
Eingabeparameter akzeptiert und beim Aufruf explizit alle zugeordneten Produkte und dann die angegebene Kategorie löscht.
Unser erster Versuch einer solchen gespeicherten Prozedur könnte wie folgt aussehen:
CREATE PROCEDURE dbo.Categories_Delete
(
@CategoryID int
)
AS
-- First, delete the associated products...
DELETE FROM Products
WHERE CategoryID = @CategoryID
-- Now delete the category
DELETE FROM Categories
WHERE CategoryID = @CategoryID
Die zugehörigen Produkte und Kategorien werden dadurch zwar definitiv gelöscht, aber nicht unter dem Dach einer Transaktion. Stellen Sie sich vor, dass es eine andere Fremdschlüsseleinschränkung Categories
gibt, die das Löschen eines bestimmten Werts verbieten @CategoryID
würde. Das Problem ist, dass in einem solchen Fall alle Produkte gelöscht werden, bevor wir versuchen, die Kategorie zu löschen. Das Nettoergebnis ist, dass diese gespeicherte Prozedur für eine solche Kategorie alle ihre Produkte entfernt, während die Kategorie bleibt, da sie noch verwandte Datensätze in einer anderen Tabelle enthält.
Wenn die gespeicherte Prozedur jedoch innerhalb des Bereichs einer Transaktion umschlossen wurde, würden die Löschvorgänge für die Products
Tabelle aufgrund eines fehlgeschlagenen Löschens für Categories
zurückgesetzt. Das folgende Skript für gespeicherte Prozeduren verwendet eine Transaktion, um die Atomarität zwischen den beiden DELETE
Anweisungen sicherzustellen:
CREATE PROCEDURE dbo.Categories_Delete
(
@CategoryID int
)
AS
BEGIN TRY
BEGIN TRANSACTION -- Start the transaction
-- First, delete the associated products...
DELETE FROM Products
WHERE CategoryID = @CategoryID
-- Now delete the category
DELETE FROM Categories
WHERE CategoryID = @CategoryID
-- If we reach here, success!
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- Whoops, there was an error
ROLLBACK TRANSACTION
-- Raise an error with the
-- details of the exception
DECLARE @ErrMsg nvarchar(4000),
@ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
Nehmen Sie sich einen Moment Zeit, um die gespeicherte Categories_Delete
Prozedur der Northwind-Datenbank hinzuzufügen. Anweisungen zum Hinzufügen gespeicherter Prozeduren zu einer Datenbank finden Sie unter Schritt 1.
Schritt 6: Aktualisieren desCategoriesTableAdapter
Während wir die Categories_Delete
gespeicherte Prozedur zur Datenbank hinzugefügt haben, ist die DAL derzeit so konfiguriert, dass ad-hoc-SQL-Anweisungen zum Ausführen des Löschens verwendet werden. Wir müssen den CategoriesTableAdapter
aktualisieren und ihn anweisen, stattdessen die gespeicherte Categories_Delete
Prozedur zu verwenden.
Hinweis
Weiter oben in diesem Tutorial haben wir mit dem NorthwindWithSprocs
DataSet gearbeitet. Dieses DataSet verfügt jedoch nur über eine einzelne Entität, ProductsDataTable
und wir müssen mit Kategorien arbeiten. Daher beziehe ich mich für den Rest dieses Tutorials, wenn ich über die Datenzugriffsebene spreche, auf das Northwind
DataSet, das wir zuerst im Tutorial Erstellen einer Datenzugriffsebene erstellt haben.
Öffnen Sie das Northwind DataSet, wählen Sie das CategoriesTableAdapter
aus, und wechseln Sie zum Eigenschaftenfenster. Die Eigenschaftenfenster listet die InsertCommand
vom TableAdapter verwendeten , UpdateCommand
, DeleteCommand
, und SelectCommand
den Namen und die Verbindungsinformationen auf. Erweitern Sie die DeleteCommand
-Eigenschaft, um ihre Details anzuzeigen. Wie Abbildung 15 zeigt, ist die DeleteCommand
s-Eigenschaft CommandType
auf Text festgelegt, wodurch sie angewiesen wird, den Text in der CommandText
Eigenschaft als Ad-hoc-SQL-Abfrage zu senden.
Abbildung 15: Wählen Sie in CategoriesTableAdapter
der Designer aus, um seine Eigenschaften im Eigenschaftenfenster anzuzeigen.
Um diese Einstellungen zu ändern, wählen Sie den Text (DeleteCommand) in der Eigenschaftenfenster aus, und wählen Sie (Neu) aus der Dropdownliste aus. Dadurch werden die Einstellungen für die CommandText
Eigenschaften , CommandType
und Parameters
gelöscht. Legen Sie als Nächstes die CommandType
-Eigenschaft auf festStoredProcedure
, und geben Sie dann den Namen der gespeicherten Prozedur für (CommandText
dbo.Categories_Delete
) ein. Wenn Sie sicherstellen, dass Sie die Eigenschaften in dieser Reihenfolge eingeben – zuerst die CommandType
und dann die CommandText
–, füllt Visual Studio automatisch die Parameters-Auflistung auf. Wenn Sie diese Eigenschaften nicht in dieser Reihenfolge eingeben, müssen Sie die Parameter manuell über die Parametersammlung Editor hinzufügen. In beiden Fällen ist es ratsam, auf die Auslassungspunkte in der Parameters-Eigenschaft zu klicken, um die Parametersammlung Editor anzuzeigen, um zu überprüfen, ob die richtigen Parametereinstellungen geändert wurden (siehe Abbildung 16). Wenn im Dialogfeld keine Parameter angezeigt werden, fügen Sie den @CategoryID
Parameter manuell hinzu (Sie müssen den @RETURN_VALUE
Parameter nicht hinzufügen).
Abbildung 16: Sicherstellen, dass die Parametereinstellungen richtig sind
Sobald die DAL aktualisiert wurde, löscht das Löschen einer Kategorie automatisch alle zugehörigen Produkte und dies unter dem Dach einer Transaktion. Um dies zu überprüfen, kehren Sie zur Seite Aktualisieren und Löschen vorhandener Binärdaten zurück, und klicken Sie für eine der Kategorien auf die Schaltfläche Löschen. Mit nur einem Mausklick werden die Kategorie und alle zugehörigen Produkte gelöscht.
Hinweis
Vor dem Testen der Categories_Delete
gespeicherten Prozedur, die eine Reihe von Produkten zusammen mit der ausgewählten Kategorie löscht, kann es ratsam sein, eine Sicherungskopie Ihrer Datenbank zu erstellen. Wenn Sie die NORTHWND.MDF
Datenbank in App_Data
verwenden, schließen Sie einfach Visual Studio, und kopieren Sie die MDF- und LDF-Dateien in App_Data
einen anderen Ordner. Nach dem Testen der Funktionalität können Sie die Datenbank wiederherstellen, indem Sie Visual Studio schließen und die aktuellen MDF- und LDF-Dateien durch App_Data
die Sicherungskopien ersetzen.
Zusammenfassung
Während der TableAdapter-Assistent automatisch gespeicherte Prozeduren für uns generiert, gibt es Zeiten, in denen wir solche gespeicherten Prozeduren bereits erstellt haben oder sie stattdessen manuell oder mit anderen Tools erstellen möchten. Um solche Szenarien zu berücksichtigen, kann der TableAdapter auch so konfiguriert werden, dass er auf eine vorhandene gespeicherte Prozedur verweist. In diesem Tutorial haben wir uns mit dem manuellen Hinzufügen gespeicherter Prozeduren zu einer Datenbank über die Visual Studio-Umgebung und das Verknüpfen der TableAdapter-Methoden mit diesen gespeicherten Prozeduren befasst. Außerdem haben wir die T-SQL-Befehle und das Skriptmuster untersucht, die zum Starten, Commiten und Rollback von Transaktionen innerhalb einer gespeicherten Prozedur verwendet werden.
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, S ren Jacob Lauritsen und Teresa Murphy. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für