Share via


Verwenden von vorhandenen gespeicherten Prozeduren für die TableAdapter-Steuerelemente des typisierten DataSet (C#)

von Scott Mitchell

PDF herunterladen

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, CommitTransactionusw.) 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.

Klicken Sie mit der rechten Maustaste auf den Ordner Gespeicherte Prozeduren, und fügen Sie eine neue gespeicherte Prozedur hinzu.

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_SelectByCategoryIDhinzu. Diese gespeicherte Prozedur akzeptiert einen einzelnen Eingabeparameter (@CategoryIDvom 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 PROCEDUREdbo.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 PROCEDUREgeä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.

Die gespeicherte Prozedur Products_SelectByCategoryID der Datenbank hinzugefügt wurde

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.

Wählen Sie die Option Vorhandene gespeicherte Prozedur verwenden aus.

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.

Wählen Sie die Products_SelectByCategoryID gespeicherte Prozedur aus.

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.

Geben Sie an, dass die gespeicherte Prozedur tabellarische Daten zurückgibt.

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

Nennen Sie die Methoden FillByCategoryID und GetProductsByCategoryID

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 GetProductsByCategoryIDerwarten 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 ProductsTableAdapterGetProductsByCategoryID 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 truefest. 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.

Abrufen von Daten aus der GetCategories-Methode der KategorienBLL-Klasse

Abbildung 7: Abrufen von Daten aus der Methode der CategoriesBLL Klasse (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)GetCategories

Legen Sie die Drop-Down Listen in den Registerkarten UPDATE, INSERT und DELETE auf (Keine) fest.

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

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

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

Abrufen von Daten aus der GetProductsByCategoryID(categoryID)-Methode

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.

Verwenden Sie die Dropdownliste Kategorien als Quelle des categoryID-Parameters.

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.

Die Produkte in der Kategorie

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 SqlTransactionund 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 TRANSACTIONbzw. .ROLLBACK TRANSACTION Wie beim ADO.NET-Ansatz müssen wir bei der Verwendung von Transaktionen aus einer gespeicherten Prozedur das folgende Muster anwenden:

  1. Geben Sie den Beginn einer Transaktion an.
  2. Führen Sie die SQL-Anweisungen aus, die die Transaktion umfassen.
  3. Wenn in einer der Anweisungen aus Schritt 2 ein Fehler auftritt, führen Sie ein Rollback für die Transaktion aus.
  4. 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).

Jede Kategorie wird in einer GridView mit den Schaltflächen

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)

Sie können eine Kategorie mit vorhandenen Produkten nicht löschen.

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 Categorieszurü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, ProductsDataTableund 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 CategoriesTableAdapteraus, und wechseln Sie zum Eigenschaftenfenster. Die Eigenschaftenfenster listet die InsertCommandvom 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.

Wählen Sie den CategoriesTableAdapter im Designer aus, um seine Eigenschaften im Eigenschaftenfenster anzuzeigen.

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 CommandTextEigenschaften , CommandTypeund Parameters gelöscht. Legen Sie als Nächstes die CommandType -Eigenschaft auf festStoredProcedure, und geben Sie dann den Namen der gespeicherten Prozedur für (CommandTextdbo.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).

Stellen Sie sicher, dass die Parametereinstellungen richtig sind.

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_Dataverwenden, 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.