Share via


Verwenden von parametrisierten Abfragen mit dem SqlDataSource-Steuerelement (C#)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial setzen wir unseren Blick auf das SqlDataSource-Steuerelement fort und erfahren, wie sie parametrisierte Abfragen definieren. Die Parameter können sowohl deklarativ als auch programmgesteuert angegeben und von einer Reihe von Speicherorten wie der Abfragezeichenfolge, dem Sitzungsstatus, anderen Steuerelementen usw. abgerufen werden.

Einführung

Im vorherigen Tutorial haben wir erfahren, wie Sie das SqlDataSource-Steuerelement verwenden, um Daten direkt aus einer Datenbank abzurufen. Mit dem Assistenten Datenquelle konfigurieren können Sie die Datenbank auswählen und dann entweder die Spalten auswählen, die aus einer Tabelle oder Sicht zurückgegeben werden sollen. geben Sie eine benutzerdefinierte SQL-Anweisung ein. oder verwenden Sie eine gespeicherte Prozedur. Unabhängig davon, ob Sie Spalten aus einer Tabelle oder Sicht auswählen oder eine benutzerdefinierte SQL-Anweisung eingeben, wird der Eigenschaft des SqlDataSource-Steuerelements SelectCommand die resultierende Ad-hoc-SQL-Anweisung SELECT zugewiesen, und diese SELECT Anweisung wird ausgeführt, wenn die SqlDataSource-Methode Select() aufgerufen wird (entweder programmgesteuert oder automatisch aus einem Datenwebsteuerelement).

Die SQL-Anweisungen SELECT , die in den vorherigen Tutorialdemos verwendet wurden, fehlen Klauseln WHERE . In einer SELECT -Anweisung kann die WHERE -Klausel verwendet werden, um die zurückgegebenen Ergebnisse zu begrenzen. Um beispielsweise die Namen von Produkten anzuzeigen, die mehr als 50,00 USD kosten, können wir die folgende Abfrage verwenden:

SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00

In der Regel werden die in einer Klausel verwendeten Werte von einer WHERE externen Quelle bestimmt, z. B. von einem Abfragezeichenfolgenwert, einer Sitzungsvariablen oder von einer Benutzereingabe aus einem Websteuerelement auf der Seite. Im Idealfall werden solche Eingaben durch die Verwendung von Parametern angegeben. Bei Microsoft SQL Server werden Parameter mit @parameterNamebezeichnet, wie in:

SELECT ProductName
FROM Products
WHERE UnitPrice > @Price

SqlDataSource unterstützt parametrisierte Abfragen sowohl für -Anweisungen als auch für SELECT - UPDATEund DELETEINSERT-Anweisungen. Darüber hinaus können die Parameterwerte automatisch aus einer Vielzahl von Quellen abgerufen werden: Abfragezeichenfolge, Sitzungsstatus, Steuerelemente auf der Seite usw. oder können programmgesteuert zugewiesen werden. In diesem Tutorial erfahren Sie, wie Sie parametrisierte Abfragen definieren und die Parameterwerte sowohl deklarativ als auch programmgesteuert angeben.

Hinweis

Im vorherigen Tutorial haben wir die ObjectDataSource, die unsere Wahl in den ersten 46 Tutorials war, mit der SqlDataSource verglichen und dabei ihre konzeptionellen Ähnlichkeiten festgestellt. Diese Ähnlichkeiten erstrecken sich auch auf Parameter. Die Parameter von ObjectDataSource, die den Eingabeparametern für die Methoden in der Geschäftslogikebene zugeordnet sind. Mit der SqlDataSource werden die Parameter direkt in der SQL-Abfrage definiert. Beide Steuerelemente verfügen über Auflistungen von Parametern für ihre Select()Methoden , Insert(), und Update()Delete() beide können diese Parameterwerte aus vordefinierten Quellen (Querystringwerte, Sitzungsvariablen usw.) aufgefüllt oder programmgesteuert zugewiesen werden.

Erstellen einer parametrisierten Abfrage

Der Assistent zum Konfigurieren von Datenquellen des SqlDataSource-Steuerelements bietet drei Möglichkeiten zum Definieren des Befehls, der zum Abrufen von Datenbankdatensätzen ausgeführt werden soll:

  • Durch Auswählen der Spalten aus einer vorhandenen Tabelle oder Sicht,
  • Wenn Sie eine benutzerdefinierte SQL-Anweisung eingeben, oder
  • Durch Auswählen einer gespeicherten Prozedur

Beim Auswählen von Spalten aus einer vorhandenen Tabelle oder Sicht müssen die Parameter für die WHERE -Klausel über das Dialogfeld Klausel hinzufügen WHERE angegeben werden. Beim Erstellen einer benutzerdefinierten SQL-Anweisung können Sie die Parameter jedoch direkt in die WHERE -Klausel eingeben (indem @parameterName Sie die einzelnen Parameter bezeichnen). Eine gespeicherte Prozedur besteht aus mindestens einer SQL-Anweisung, und diese Anweisungen können parametrisiert werden. Die in den SQL-Anweisungen verwendeten Parameter müssen jedoch als Eingabeparameter an die gespeicherte Prozedur übergeben werden.

Da das Erstellen einer parametrisierten Abfrage davon abhängt, wie sqlDataSource s SelectCommand angegeben wird, sehen wir uns alle drei Ansätze an. Öffnen Sie zunächst die ParameterizedQueries.aspx Seite im SqlDataSource Ordner, ziehen Sie ein SqlDataSource-Steuerelement aus der Toolbox auf die Designer, und legen Sie es ID auf festProducts25BucksAndUnderDataSource. Klicken Sie als Nächstes im Smarttag des Steuerelements auf den Link Datenquelle konfigurieren. Wählen Sie die zu verwendende Datenbank (NORTHWINDConnectionString) aus, und klicken Sie auf Weiter.

Schritt 1: Hinzufügen einer WHERE-Klausel beim Auswählen der Spalten aus einer Tabelle oder Sicht

Wenn Sie die Daten auswählen, die mit dem SqlDataSource-Steuerelement aus der Datenbank zurückgegeben werden sollen, können Sie mit dem Assistenten Datenquelle konfigurieren einfach die Spalten auswählen, die aus einer vorhandenen Tabelle oder Sicht zurückgegeben werden sollen (siehe Abbildung 1). Dadurch wird automatisch eine SQL-Anweisung SELECT erstellt, die an die Datenbank gesendet wird, wenn die SqlDataSource-Methode Select() aufgerufen wird. Wählen Sie wie im vorherigen Tutorial die Tabelle Products aus der Dropdownliste aus, und überprüfen Sie die ProductIDSpalten , ProductNameund UnitPrice .

Wählen Sie die Spalten aus, die aus einer Tabelle oder Ansicht zurückgegeben werden sollen.

Abbildung 1: Auswählen der Spalten, die aus einer Tabelle oder Ansicht zurückgegeben werden sollen (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Um eine WHERE Klausel in die SELECT -Anweisung aufzunehmen, klicken Sie auf die WHERE Schaltfläche, die das Dialogfeld Klausel hinzufügen WHERE öffnet (siehe Abbildung 2). Um einen Parameter hinzuzufügen, um die von der SELECT Abfrage zurückgegebenen Ergebnisse einzuschränken, wählen Sie zuerst die Spalte aus, nach der die Daten gefiltert werden sollen. Wählen Sie als Nächstes den Operator aus, der zum Filtern verwendet werden soll (=, <, <=, >usw.). Wählen Sie schließlich die Quelle des Werts des Parameters aus, z. B. aus der Abfragezeichenfolge oder dem Sitzungszustand. Klicken Sie nach dem Konfigurieren des Parameters auf die Schaltfläche Hinzufügen, um ihn in die SELECT Abfrage aufzunehmen.

In diesem Beispiel geben wir nur die Ergebnisse zurück, bei denen der UnitPrice Wert kleiner oder gleich $25,00 ist. Wählen Sie UnitPrice daher aus der Dropdownliste Spalte und <= aus der Dropdownliste Operator aus. Wenn Sie einen hartcodierten Parameterwert verwenden (z. B. $25,00) oder wenn der Parameterwert programmgesteuert angegeben werden soll, wählen Sie in der Dropdownliste Quelle die Option Keine aus. Geben Sie als Nächstes den hartcodierten Parameterwert in das Textfeld Wert 25.00 ein, und schließen Sie den Vorgang ab, indem Sie auf die Schaltfläche Hinzufügen klicken.

Einschränken der Ergebnisse, die aus dem Dialogfeld WHERE-Klausel hinzufügen zurückgegeben werden

Abbildung 2: Einschränken der aus dem Dialogfeld Klausel hinzufügen WHERE zurückgegebenen Ergebnisse (Klicken Sie, um das bild in voller Größe anzuzeigen)

Klicken Sie nach dem Hinzufügen des Parameters auf OK, um zum Assistenten Datenquelle konfigurieren zurückzukehren. Die SELECT Anweisung am unteren Rand des Assistenten sollte jetzt eine WHERE Klausel mit einem Parameter namens @UnitPriceenthalten:

SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)

Hinweis

Wenn Sie im Dialogfeld Klausel hinzufügen WHERE mehrere Bedingungen in der WHERE -Klausel angeben, verknüpft der Assistent diese mit dem AND Operator. Wenn Sie eine OR in die WHERE -Klausel einschließen müssen (z WHERE UnitPrice <= @UnitPrice OR Discontinued = 1. B. ), müssen Sie die SELECT Anweisung über den Bildschirm für benutzerdefinierte SQL-Anweisungen erstellen.

Schließen Sie die Konfiguration der SqlDataSource ab (klicken Sie auf Weiter und dann auf Fertig stellen), und überprüfen Sie dann das deklarative Markup des SqlDataSource-Markups. Das Markup enthält jetzt eine <SelectParameters> Auflistung, die die Quellen für die Parameter in der SelectCommandbeschreibt.

<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice]
        FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
    <SelectParameters>
        <asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
    </SelectParameters>
</asp:SqlDataSource>

Wenn die SqlDataSource-Methode Select() aufgerufen wird, wird der UnitPrice Parameterwert (25.00) auf den @UnitPrice Parameter in angewendet SelectCommand , bevor er an die Datenbank gesendet wird. Das Nettoergebnis ist, dass nur Produkte unter oder gleich 25,00 USD aus der Products Tabelle zurückgegeben werden. Um dies zu bestätigen, fügen Sie der Seite eine GridView hinzu, binden sie an diese Datenquelle, und zeigen Sie die Seite dann über einen Browser an. Es sollten nur die Produkte aufgeführt werden, die kleiner als oder gleich 25,00 USD sind, wie Abbildung 3 bestätigt.

Es werden nur Produkte angezeigt, die kleiner als oder gleich 25,00 USD sind.

Abbildung 3: Nur Produkte, die kleiner als oder gleich 25,00 USD sind, werden angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Schritt 2: Hinzufügen von Parametern zu einer benutzerdefinierten SQL-Anweisung

Beim Hinzufügen einer benutzerdefinierten SQL-Anweisung können Sie die WHERE Klausel explizit eingeben oder einen Wert in der Zelle Filter des Abfrage-Generators angeben. Um dies zu veranschaulichen, zeigen wir nur die Produkte in einer GridView an, deren Preise unter einem bestimmten Schwellenwert liegen. Fügen Sie zunächst ParameterizedQueries.aspx der Seite ein Textfeld hinzu, um diesen Schwellenwert vom Benutzer zu erfassen. Legen Sie die TextBox-Eigenschaft ID auf fest MaxPrice. Fügen Sie ein Button-Websteuerelement hinzu, und legen Sie dessen Text Eigenschaft auf Übereinstimmende Produkte anzeigen fest.

Ziehen Sie als Nächstes eine GridView auf die Seite, und wählen Sie aus ihrem Smarttag aus, um eine neue SqlDataSource mit dem Namen ProductsFilteredByPriceDataSourcezu erstellen. Fahren Sie im Assistenten Datenquelle konfigurieren mit dem Bildschirm Angeben einer benutzerdefinierten SQL-Anweisung oder gespeicherten Prozedur fort (siehe Abbildung 4), und geben Sie die folgende Abfrage ein:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice

Klicken Sie nach der Eingabe der Abfrage (manuell oder über den Abfrage-Generator) auf Weiter.

Zurückgeben nur der Produkte, die kleiner oder gleich einem Parameterwert sind

Abbildung 4: Zurückgeben nur der Produkte, die kleiner als oder gleich einem Parameterwert sind (Klicken Sie, um das bild in voller Größe anzuzeigen)

Da die Abfrage Parameter enthält, werden wir auf dem nächsten Bildschirm im Assistenten zur Quelle der Parameterwerte aufgefordert. Wählen Sie in der Dropdownliste Parameterquelle die Option Steuerelement und MaxPrice (der Wert des TextBox-Steuerelements ID ) in der Dropdownliste ControlID aus. Sie können auch einen optionalen Standardwert eingeben, der für den Fall verwendet werden soll, dass der Benutzer keinen Text in das MaxPrice Textfeld eingegeben hat. Geben Sie vorerst keinen Standardwert ein.

Die Texteigenschaft von MaxPrice TextBox wird als Parameterquelle verwendet.

Abbildung 5: Die MaxPrice TextBox s-Eigenschaft Text wird als Parameterquelle verwendet (Klicken Sie, um das bild in voller Größe anzuzeigen)

Schließen Sie den Assistenten Datenquelle konfigurieren ab, indem Sie auf Weiter und dann auf Fertig stellen klicken. Das deklarative Markup für GridView, TextBox, Button und SqlDataSource folgt:

Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
 
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
    Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
    DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            HtmlEncode="False" DataFormatString="{0:c}"
            SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT ProductName, UnitPrice 
        FROM Products WHERE UnitPrice <= @MaximumPrice">
    <SelectParameters>
        <asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
            PropertyName="Text" />
    </SelectParameters>
</asp:SqlDataSource>

Beachten Sie, dass der Parameter im Abschnitt von SqlDataSource <SelectParameters> ein ControlParameterist, der zusätzliche Eigenschaften wie ControlID und PropertyNameenthält. Wenn die SqlDataSource-Methode Select() aufgerufen wird, greift die den ControlParameter Wert aus der angegebenen Websteuerelementeigenschaft ab und weist ihn dem entsprechenden Parameter in der SelectCommandzu. In diesem Beispiel wird die MaxPrice s Text-Eigenschaft als @MaxPrice Parameterwert verwendet.

Nehmen Sie sich eine Minute Zeit, um diese Seite über einen Browser anzuzeigen. Wenn Sie die Seite zum ersten Mal besuchen oder wenn dem MaxPrice Textfeld ein Wert fehlt, werden keine Datensätze in der GridView angezeigt.

Es werden keine Datensätze angezeigt, wenn das Textfeld MaxPrice leer ist

Abbildung 6: Keine Datensätze werden angezeigt, wenn das MaxPrice Textfeld leer ist (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Der Grund, warum keine Produkte angezeigt werden, liegt daran, dass standardmäßig eine leere Zeichenfolge für einen Parameterwert in einen Datenbankwert NULL konvertiert wird. Da der Vergleich von [UnitPrice] <= NULL immer als False ausgewertet wird, werden keine Ergebnisse zurückgegeben.

Geben Sie einen Wert wie 5.00 in das Textfeld ein, und klicken Sie auf die Schaltfläche Übereinstimmende Produkte anzeigen. Beim Postback informiert SqlDataSource die GridView darüber, dass sich eine ihrer Parameterquellen geändert hat. Folglich wird gridView an die SqlDataSource neu gebunden und zeigt diese Produkte unter oder gleich 5,00 USD an.

Produkte, die kleiner als oder gleich $5.00 sind, werden angezeigt

Abbildung 7: Produkte, die kleiner als oder gleich 5,00 USD sind, werden angezeigt (Klicken Sie, um das bild in voller Größe anzuzeigen)

Anfängliche Anzeige aller Produkte

Anstatt beim ersten Laden der Seite keine Produkte anzuzeigen, sollten alle Produkte angezeigt werden. Eine Möglichkeit, alle Produkte aufzulisten, wenn das MaxPrice TextBox leer ist, besteht darin, den Standardwert des Parameters auf einen wahnsinnig hohen Wert wie 1000000 festzulegen, da es unwahrscheinlich ist, dass Northwind Traders jemals einen Bestand haben wird, dessen Einzelpreis 1.000.000 USD überschreitet. Dieser Ansatz ist jedoch kurzsichtig und funktioniert in anderen Situationen möglicherweise nicht.

In den vorherigen Tutorials – Deklarative Parameter und Master-/Detailfilterung mit einer DropDownList sahen wir uns mit einem ähnlichen Problem konfrontiert. Unsere Lösung bestand darin, diese Logik in die Geschäftslogikebene zu bringen. Insbesondere untersuchte die BLL den eingehenden Wert, und wenn es sich um einen reservierten Wert handelte NULL , wurde der Aufruf an die DAL-Methode weitergeleitet, die alle Datensätze zurückgibt. Wenn der eingehende Wert ein normaler Filterwert war, wurde ein Aufruf der DAL-Methode durchgeführt, die eine SQL-Anweisung ausgeführt hat, die eine parametrisierte WHERE Klausel mit dem angegebenen Wert verwendet.

Leider umgehen wir die Architektur, wenn wir die SqlDataSource verwenden. Stattdessen müssen wir die SQL-Anweisung anpassen, um alle Datensätze intelligent zu erfassen, wenn der @MaximumPrice Parameter oder ein reservierter Wert ist NULL . Für diese Übung haben wir es so, dass, wenn der @MaximumPrice Parameter gleich -1.0ist, alle Datensätze zurückgegeben werden (-1.0 funktioniert als reservierter Wert, da kein Produkt einen negativen UnitPrice Wert haben kann). Um dies zu erreichen, können wir die folgende SQL-Anweisung verwenden:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

Diese WHERE Klausel gibt alle Datensätze zurück, wenn der @MaximumPrice Parameter gleich ist -1.0. Wenn der Parameterwert nicht -1.0ist, werden nur die Produkte zurückgegeben, deren UnitPrice Wert kleiner oder gleich dem @MaximumPrice Parameterwert ist. Wenn Sie den Standardwert des @MaximumPrice Parameters auf -1.0festlegen, wird auf der ersten Seite geladen (oder immer, wenn das MaxPrice Textfeld leer ist), @MaximumPrice der Wert von -1.0 aufweist, und alle Produkte werden angezeigt.

Jetzt werden alle Produkte angezeigt, wenn das Textfeld MaxPrice leer ist

Abbildung 8: Jetzt werden alle Produkte angezeigt, wenn das MaxPrice Textfeld leer ist (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Bei diesem Ansatz gibt es einige Einschränkungen zu beachten. Beachten Sie zunächst, dass der Datentyp des Parameters von seiner Verwendung in der SQL-Abfrage abgeleitet wird. Wenn Sie die WHERE Klausel von @MaximumPrice = -1.0 in @MaximumPrice = -1ändern, behandelt die Runtime den Parameter als ganze Zahl. Wenn Sie dann versuchen, das MaxPrice Textfeld einem Dezimalwert (z. B. 5.00) zuzuweisen, tritt ein Fehler auf, da 5.00 nicht in eine ganze Zahl konvertiert werden kann. Um dies zu beheben, stellen Sie entweder sicher, dass Sie in der WHERE -Klausel verwenden@MaximumPrice = -1.0, oder legen Sie die ControlParameter Eigenschaft des Type Objekts auf Decimal fest.

Zweitens kann die Abfrage-Engine durch Hinzufügen von WHERE zur OR @MaximumPrice = -1.0 -Klausel keinen Index für UnitPrice verwenden (vorausgesetzt, dass ein Index vorhanden ist), was zu einer Tabellenüberprüfung führt. Dies kann sich auf die Leistung auswirken, wenn eine ausreichende Anzahl von Datensätzen in der Products Tabelle vorhanden ist. Ein besserer Ansatz wäre es, diese Logik in eine gespeicherte Prozedur zu verschieben, in der eine IF Anweisung entweder eine SELECT Abfrage aus der Products Tabelle ohne Klausel WHERE ausführt, wenn alle Datensätze zurückgegeben werden müssen, oder eine, deren WHERE Klausel nur die UnitPrice Kriterien enthält, sodass ein Index verwendet werden kann.

Schritt 3: Erstellen und Verwenden parametrisierter gespeicherter Prozeduren

Gespeicherte Prozeduren können eine Reihe von Eingabeparametern enthalten, die dann in den SQL-Anweisungen verwendet werden können, die in der gespeicherten Prozedur definiert sind. Beim Konfigurieren der SqlDataSource für die Verwendung einer gespeicherten Prozedur, die Eingabeparameter akzeptiert, können diese Parameterwerte mit den gleichen Techniken wie mit Ad-hoc-SQL-Anweisungen angegeben werden.

Um die Verwendung gespeicherter Prozeduren in sqlDataSource zu veranschaulichen, erstellen wir eine neue gespeicherte Prozedur in der Northwind-Datenbank, GetProductsByCategorydie einen Parameter namens @CategoryID akzeptiert und alle Spalten der Produkte zurückgibt, deren CategoryID Spalte mit übereinstimmt @CategoryID. Um eine gespeicherte Prozedur zu erstellen, wechseln Sie zum server-Explorer, und führen Sie einen Drilldown in die Datenbank ausNORTHWND.MDF. (Wenn die Server-Explorer nicht angezeigt wird, rufen Sie ihn auf, indem Sie zum Menü Ansicht wechseln und die Option Server Explorer auswählen.)

Klicken Sie in der NORTHWND.MDF Datenbank mit der rechten Maustaste auf den Ordner Gespeicherte Prozeduren, wählen Sie Neue gespeicherte Prozedur hinzufügen aus, und geben Sie die folgende Syntax ein:

CREATE PROCEDURE dbo.GetProductsByCategory
(
      @CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID

Klicken Sie auf das Symbol Speichern (oder STRG+S), um die gespeicherte Prozedur zu speichern. Sie können die gespeicherte Prozedur testen, indem Sie im Ordner Gespeicherte Prozeduren mit der rechten Maustaste darauf klicken und Ausführen auswählen. Dadurch werden Sie zur Eingabe der Parameter der gespeicherten Prozedur (@CategoryIDin diesem instance) aufgefordert, wonach die Ergebnisse im Ausgabefenster angezeigt werden.

Die gespeicherte GetProductsByCategory-Prozedur bei Ausführung mit einem <span class=@CategoryID von 1" />

Abbildung 9: Die GetProductsByCategory gespeicherte Prozedur bei Ausführung mit einer @CategoryID von 1 (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Verwenden Sie diese gespeicherte Prozedur, um alle Produkte in der Kategorie Getränke in einer GridView anzuzeigen. Fügen Sie der Seite eine neue GridView hinzu, und binden Sie sie an eine neue SqlDataSource mit dem Namen BeverageProductsDataSource. Fahren Sie mit dem Bildschirm Benutzerdefinierte SQL-Anweisung oder gespeicherte Prozedur angeben fort, wählen Sie das Optionsfeld Gespeicherte Prozedur aus, und wählen Sie die GetProductsByCategory gespeicherte Prozedur aus der Dropdownliste aus.

Wählen Sie die gespeicherte GetProductsByCategory-Prozedur aus der Drop-Down-Liste aus.

Abbildung 10: Auswählen der GetProductsByCategory gespeicherten Prozedur aus der liste Drop-Down (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Da die gespeicherte Prozedur einen Eingabeparameter akzeptiert (@CategoryID), werden wir durch Klicken auf Weiter aufgefordert, die Quelle für diesen Parameterwert anzugeben. CategoryID Getränke ist 1. Behalten Sie daher die Dropdownliste Parameterquelle bei Keine bei, und geben Sie 1 in das Textfeld DefaultValue ein.

Verwenden Sie einen Hard-Coded Wert von 1, um die Produkte in der Kategorie Getränke zurückzugeben.

Abbildung 11: Verwenden Sie einen Hard-Coded Wert von 1, um die Produkte in der Getränkekategorie zurückzugeben (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Wie das folgende deklarative Markup zeigt, wird die SqlDataSource-Eigenschaft SelectCommand bei Verwendung einer gespeicherten Prozedur auf den Namen der gespeicherten Prozedur und die SelectCommandType -Eigenschaft auf StoredProcedurefestgelegt, was angibt, dass der name SelectCommand einer gespeicherten Prozedur und nicht eine Ad-hoc-SQL-Anweisung ist.

<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Testen Sie die Seite in einem Browser. Es werden nur die Produkte angezeigt, die zur Kategorie Getränke gehören, obwohl alle Produktfelder angezeigt werden, da die GetProductsByCategory gespeicherte Prozedur alle Spalten aus der Products Tabelle zurückgibt. Natürlich können wir die im GridView-Dialogfeld Spalten bearbeiten angezeigten Felder einschränken oder anpassen.

Alle Getränke werden angezeigt

Abbildung 12: Alle Getränke werden angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 4: Programmgesteuertes Aufrufen einer Select()-Anweisung von SqlDataSource

Die Beispiele, die wir im vorherigen Tutorial und in diesem Tutorial bisher gesehen haben, haben SqlDataSource-Steuerelemente direkt an eine GridView gebunden. Auf die Daten des SqlDataSource-Steuerelements kann jedoch programmgesteuert zugegriffen und im Code aufgezählt werden. Dies kann besonders nützlich sein, wenn Sie Daten abfragen müssen, um sie zu überprüfen, aber nicht anzeigen müssen. Anstatt den gesamten Boilerplate-ADO.NET Code schreiben zu müssen, um eine Verbindung mit der Datenbank herzustellen, den Befehl angeben und die Ergebnisse abrufen zu müssen, können Sie sqlDataSource diesen monotonen Code verarbeiten lassen.

Stellen Sie sich zum programmgesteuerten Arbeiten mit den SqlDataSource-Daten vor, dass Ihr Chef Sie mit einer Anforderung zum Erstellen einer Webseite angesprochen hat, auf der der Name einer zufällig ausgewählten Kategorie und der zugehörigen Produkte angezeigt wird. Das heißt, wenn ein Benutzer diese Seite besucht, möchten wir nach dem Zufallsprinzip eine Kategorie aus der Categories Tabelle auswählen, den Kategorienamen anzeigen und dann die Produkte auflisten, die zu dieser Kategorie gehören.

Dazu benötigen wir zwei SqlDataSource-Steuerelemente, eines zum Abrufen einer zufälligen Kategorie aus der Categories Tabelle und eines, um die Produkte der Kategorie abzurufen. In diesem Schritt erstellen wir die SqlDataSource, die einen zufälligen Kategoriedatensatz abruft. Schritt 5 befasst sich mit dem Erstellen der SqlDataSource, die die Produkte der Kategorie abruft.

Beginnen Sie mit dem Hinzufügen einer SqlDataSource zu ParameterizedQueries.aspx , und legen Sie ihre ID auf fest RandomCategoryDataSource. Konfigurieren Sie sie so, dass die folgende SQL-Abfrage verwendet wird:

SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()

ORDER BY NEWID() gibt die Datensätze in zufälliger Reihenfolge zurück (siehe Verwenden NEWID() von Datensätzen nach dem Zufallsprinzip). SELECT TOP 1 gibt den ersten Datensatz aus dem Resultset zurück. Zusammen gibt diese Abfrage die CategoryID Spaltenwerte und CategoryName aus einer einzelnen, zufällig ausgewählten Kategorie zurück.

Um den Wert der Kategorie CategoryName anzuzeigen, fügen Sie der Seite ein Label-Websteuerelement hinzu, legen ihre ID Eigenschaft auf fest CategoryNameLabel, und löschen Sie dessen Text Eigenschaft. Um die Daten programmgesteuert aus einem SqlDataSource-Steuerelement abzurufen, müssen wir dessen Select() Methode aufrufen. Die Select() -Methode erwartet einen einzelnen Eingabeparameter vom Typ DataSourceSelectArguments, der angibt, wie die Daten vor der Rückgabe gesendet werden sollen. Dies kann Anweisungen zum Sortieren und Filtern der Daten enthalten und wird von den Datenwebsteuerelementen beim Sortieren oder Paging der Daten aus einem SqlDataSource-Steuerelement verwendet. Für unser Beispiel müssen die Daten jedoch nicht geändert werden, bevor sie zurückgegeben werden, und daher wird das DataSourceSelectArguments.Empty Objekt übergeben.

Die Select() -Methode gibt ein -Objekt zurück, das implementiert IEnumerable. Der genaue Typ, der zurückgegeben wird, hängt vom Wert der Eigenschaft des SqlDataSource-Steuerelements DataSourceModeab. Wie im vorherigen Tutorial erläutert, kann diese Eigenschaft auf einen Wert von oder DataSetDataReaderfestgelegt werden. Wenn auf DataSetfestgelegt ist, gibt die Select() -Methode ein DataView-Objekt zurück. Wenn auf DataReaderfestgelegt ist, gibt sie ein Objekt zurück, das implementiert IDataReader. Da die RandomCategoryDataSource SqlDataSource-Eigenschaft DataSourceMode auf DataSet (Standard) festgelegt ist, arbeiten wir mit einem DataView-Objekt.

Der folgende Code veranschaulicht, wie sie die Datensätze aus der RandomCategoryDataSource SqlDataSource als DataView abrufen und wie der CategoryName Spaltenwert aus der ersten DataView-Zeile gelesen wird:

protected void Page_Load(object sender, EventArgs e)
{
    // Get the data from the SqlDataSource as a DataView
    DataView randomCategoryView =
        (DataView)RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty);
    if (randomCategoryView.Count > 0)
    {
        // Assign the CategoryName value to the Label
        CategoryNameLabel.Text =
            string.Format("Here are Products in the {0} Category...",
                randomCategoryView[0]["CategoryName"].ToString());
    }
}

randomCategoryView[0] gibt die erste DataRowView in der DataView zurück. randomCategoryView[0]["CategoryName"] gibt den Wert der CategoryName Spalte in dieser ersten Zeile zurück. Beachten Sie, dass die DataView lose typisiert ist. Um auf einen bestimmten Spaltenwert zu verweisen, müssen wir den Namen der Spalte als Zeichenfolge übergeben ( in diesem Fall CategoryName). Abbildung 13 zeigt die Meldung, die beim Anzeigen der CategoryNameLabel Seite in angezeigt wird. Natürlich wird der angezeigte tatsächliche Kategoriename von der RandomCategoryDataSource SqlDataSource bei jedem Seitenbesuch (einschließlich Postbacks) zufällig ausgewählt.

Der Name der zufällig ausgewählten Kategorie wird angezeigt.

Abbildung 13: Der Zufällig ausgewählte Kategoriename wird angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Hinweis

Wenn die Eigenschaft des SqlDataSource-Steuerelements DataSourceMode auf DataReaderfestgelegt wurde, hätte der Rückgabewert der Select() -Methode in IDataReaderumgewandelt werden müssen. Um den CategoryName Spaltenwert aus der ersten Zeile zu lesen, verwenden wir Code wie:

if (randomCategoryReader.Read())
{
   string categoryName = randomCategoryReader["CategoryName"].ToString();
   ...
}

Wenn SqlDataSource zufällig eine Kategorie auswählt, können wir die GridView hinzufügen, in der die Produkte der Kategorie aufgelistet sind.

Hinweis

Anstatt ein Label-Websteuerelement zum Anzeigen des Kategorienamens zu verwenden, hätten wir der Seite eine FormView oder DetailsView hinzufügen können, die an die SqlDataSource gebunden ist. Mithilfe der Bezeichnung konnten wir jedoch untersuchen, wie die SqlDataSource-Anweisung Select() programmgesteuert aufgerufen und mit den resultierenden Daten im Code gearbeitet wird.

Schritt 5: Programmgesteuertes Zuweisen von Parameterwerten

Alle Beispiele, die wir bisher in diesem Tutorial gesehen haben, haben entweder einen hartcodierten Parameterwert oder einen wert aus einer der vordefinierten Parameterquellen (ein Abfragezeichenfolgenwert, ein Websteuerelement auf der Seite usw.) verwendet. Die Parameter des SqlDataSource-Steuerelements können jedoch auch programmgesteuert festgelegt werden. Um unser aktuelles Beispiel abzuschließen, benötigen wir eine SqlDataSource, die alle Produkte zurückgibt, die zu einer angegebenen Kategorie gehören. Diese SqlDataSource verfügt über einen CategoryID Parameter, dessen Wert basierend auf dem CategoryID Spaltenwert festgelegt werden muss, der von sqlDataSource RandomCategoryDataSource im Page_Load Ereignishandler zurückgegeben wird.

Fügen Sie zunächst der Seite ein GridView-Element hinzu, und binden Sie sie an eine neue SqlDataSource namens ProductsByCategoryDataSource. Wie in Schritt 3 konfigurieren Sie sqlDataSource so, dass die GetProductsByCategory gespeicherte Prozedur aufgerufen wird. Lassen Sie die Dropdownliste Parameterquelle auf Keine festgelegt, geben Sie jedoch keinen Standardwert ein, da wir diesen Standardwert programmgesteuert festlegen.

Screenshot: Fenster

Abbildung 14: Geben Sie keine Parameterquelle oder einen Standardwert an (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nach Abschluss des SqlDataSource-Assistenten sollte das resultierende deklarative Markup in etwa wie folgt aussehen:

<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Wir können den DefaultValue des CategoryID Parameters programmgesteuert im Page_Load Ereignishandler zuweisen:

// Assign the ProductsByCategoryDataSource's
// CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
    randomCategoryView[0]["CategoryID"].ToString();

Mit dieser Ergänzung enthält die Seite eine GridView, die die Produkte anzeigt, die der zufällig ausgewählten Kategorie zugeordnet sind.

Screenshot: Seite

Abbildung 15: Geben Sie keine Parameterquelle oder einen Standardwert an (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Zusammenfassung

Mit SqlDataSource können Seitenentwickler parametrisierte Abfragen definieren, deren Parameterwerte hartcodiert, aus vordefinierten Parameterquellen abgerufen oder programmgesteuert zugewiesen werden können. In diesem Tutorial haben wir erfahren, wie Sie eine parametrisierte Abfrage über den Assistenten zum Konfigurieren von Datenquellen sowohl für Ad-hoc-SQL-Abfragen als auch für gespeicherte Prozeduren erstellen. Außerdem haben wir die Verwendung hartcodierter Parameterquellen, eines Websteuerelements als Parameterquelle und der programmgesteuerten Angabe des Parameterwerts untersucht.

Wie bei ObjectDataSource bietet sqlDataSource auch Funktionen zum Ändern der zugrunde liegenden Daten. Im nächsten Tutorial erfahren Sie, wie Sie die Anweisungen , UPDATEund DELETE mit sqlDataSource definierenINSERT. Nachdem diese Anweisungen hinzugefügt wurden, können wir die integrierten Funktionen zum Einfügen, Bearbeiten und Löschen verwenden, die den GridView-, DetailsView- und FormView-Steuerelementen innewohnen.

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 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Hauptprüfer für dieses Tutorial waren Scott Clyde, Randell Schmidt und Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.