Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Scott Mitchell
In diesem Tutorial setzen wir unsere Betrachtung des SqlDataSource-Controls fort und lernen, wie parametrisierte Abfragen definiert werden. Die Parameter können sowohl deklarativ als auch programmgesteuert angegeben werden und aus einer Reihe von Speicherorten wie der Abfragezeichenfolge, dem Sitzungsstatus, anderen Steuerelementen und mehr abgerufen werden.
Einleitung
Im vorherigen Lernprogramm haben wir erfahren, wie Sie das SqlDataSource-Steuerelement verwenden, um Daten direkt aus einer Datenbank abzurufen. Mithilfe des Assistenten "Datenquelle konfigurieren" können wir die Datenbank auswählen und dann entweder die Spalten auswählen, die aus einer Tabelle oder Ansicht 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 Ansicht auswählen oder eine benutzerdefinierte SQL-Anweisung eingeben, wird die Eigenschaft des SqlDataSource-Steuerelements SelectCommand
der resultierenden Ad-hoc-SQL-Anweisung SELECT
zugewiesen, und es handelt sich um diese SELECT
Anweisung, die ausgeführt wird, wenn die SqlDataSource-Methode Select()
aufgerufen wird (entweder programmgesteuert oder automatisch aus einem Datenwebsteuerelement).
Die SQL-Anweisungen SELECT
, die in den Demos des vorherigen Tutorials verwendet wurden, fehlten WHERE
-Klauseln. In einer SELECT
Anweisung kann die WHERE
Klausel verwendet werden, um die zurückgegebenen Ergebnisse einzuschränken. Um beispielsweise die Namen von Produkten anzuzeigen, die mehr als 50,00 $ kosten, könnten wir die folgende Abfrage verwenden:
SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00
In der Regel werden die in einer WHERE
Klausel verwendeten Werte von einer externen Quelle bestimmt, z. B. von einem Abfragezeichenfolgenwert, einer Sitzungsvariable oder von Benutzereingaben eines Websteuerelements auf der Seite. Im Idealfall werden solche Eingaben über die Verwendung von Parametern angegeben. In Microsoft SQL Server werden Parameter mit @parameterName
angegeben, wie im Beispiel:
SELECT ProductName
FROM Products
WHERE UnitPrice > @Price
SqlDataSource unterstützt parametrisierte Abfragen, sowohl für SELECT
-Anweisungen als auch für INSERT
, UPDATE
- und DELETE
-Anweisungen. Darüber hinaus können die Parameterwerte automatisch aus einer Vielzahl von Quellen abgerufen werden, wie der Abfragezeichenfolge, dem Sitzungszustand, den Steuerelementen auf der Seite usw., oder sie können programmgesteuert zugewiesen werden. In diesem Lernprogramm wird erläutert, wie parametrisierte Abfragen definiert werden und wie sie die Parameterwerte sowohl deklarativ als auch programmgesteuert angeben.
Hinweis
Im vorherigen Lernprogramm haben wir die ObjectDataSource verglichen, die unser Wahltool für die ersten 46 Lernprogramme mit der SqlDataSource war, wobei sie ihre konzeptionellen Ähnlichkeiten notiert. Diese Ähnlichkeiten erstrecken sich auch auf Parameter. Die Parameter von ObjectDataSource, die den Eingabeparametern der Methoden in der Geschäftslogikebene zugeordnet sind. Mit sqlDataSource werden die Parameter direkt in der SQL-Abfrage definiert. Beide Steuerelemente verfügen über Auflistungen von Parametern für ihre Select()
, Insert()
, Update()
und Delete()
-Methoden, und beide können diese Parameterwerte aus vordefinierten Quellen (Abfragezeichenfolgenwerte, Sitzungsvariablen usw.) stammen oder programmgesteuert zugewiesen werden.
Erstellen einer parametrisierten Abfrage
Der Assistent zur Konfiguration der SqlDataSource-Datenquelle bietet drei Möglichkeiten, den Befehl zu definieren, der zum Abrufen von Datenbankdatensätzen ausgeführt wird.
- Indem Sie die Spalten aus einer vorhandenen Tabelle oder Ansicht auswählen,
- Durch Eingabe einer benutzerdefinierten SQL-Anweisung oder
- Durch Auswählen einer gespeicherten Prozedur
Beim Auswählen von Spalten aus einer vorhandenen Tabelle oder Ansicht 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 jedoch die Parameter direkt in die WHERE
-Klausel eingeben, indem Sie @parameterName
verwenden, um jeden Parameter anzugeben. Eine gespeicherte Prozedur besteht aus einer oder mehreren SQL-Anweisungen, 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 die SqlDataSource s SelectCommand
angegeben wird, werfen wir einen Blick auf alle drei Ansätze. Um zu beginnen, öffnen Sie die ParameterizedQueries.aspx
Seite im SqlDataSource
Ordner, ziehen Sie ein SqlDataSource-Steuerelement aus der Toolbox auf den Designer, und setzen Sie dessen ID
auf Products25BucksAndUnderDataSource
. Klicken Sie als Nächstes auf den Link "Datenquelle konfigurieren" aus dem Smarttag des Steuerelements. 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 Ansicht
Wenn Sie die Daten auswählen, die mit dem SqlDataSource-Steuerelement aus der Datenbank zurückgegeben werden sollen, können wir im Assistenten zum Konfigurieren von Datenquellen einfach die Spalten auswählen, die aus einer vorhandenen Tabelle oder Ansicht 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 "Produkte" aus der Dropdown-Liste und überprüfen Sie die Spalten ProductID
, ProductName
und UnitPrice
.
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 einzuschließen, klicken Sie auf die WHERE
Schaltfläche, die das Dialogfeld "Klausel hinzufügen WHERE
" anzeigt (siehe Abbildung 2). Wenn Sie einen Parameter hinzufügen möchten, 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 für die Filterung verwendet werden soll (=, <= <, >usw.). Wählen Sie schließlich die Quelle des Parameterwerts 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 einzuschließen.
In diesem Beispiel geben wir nur die Ergebnisse zurück, bei denen der UnitPrice
Wert kleiner oder gleich 25,00 $ ist. Wählen Sie daher UnitPrice
in der Dropdownliste "Spalte" und <= in der Dropdownliste "Operator" aus. Wenn Sie einen hartcodierten Parameterwert (z. B. $25,00) verwenden oder wenn der Parameterwert programmgesteuert angegeben werden soll, wählen Sie "Keine" aus der Dropdownliste "Quelle" 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.
Abbildung 2: Einschränken der ergebnisse, die aus dem Dialogfeld "Klausel hinzufügen WHERE
" zurückgegeben werden (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 nun eine WHERE
Klausel mit einem Parameter mit dem Namen @UnitPrice
" enthalten:
SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)
Hinweis
Wenn Sie mehrere Bedingungen in der WHERE
Klausel aus dem Dialogfeld "Klausel hinzufügen WHERE
" angeben, verknüpft der Assistent sie mit dem AND
Operator. Wenn Sie ein OR
in die WHERE
Klausel einschließen müssen (z. B. WHERE UnitPrice <= @UnitPrice OR Discontinued = 1
), müssen Sie die SELECT
Anweisung über den benutzerdefinierten SQL-Anweisungsbildschirm erstellen.
Konfigurieren Sie die SqlDataSource (klicken Sie auf Weiter, dann fertig stellen), und prüfen Sie dann das deklarative Markup von SqlDataSource. Das Markup umfasst nun eine <SelectParameters>
Sammlung, die die Quellen für die Parameter in der SelectCommand
darstellt.
<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 Parameter in der @UnitPrice
SelectCommand
Datenbank angewendet, bevor er an die Datenbank gesendet wird. Das Nettoergebnis ist, dass nur die Produkte, die kleiner oder gleich 25,00 $ sind, aus der Products
Tabelle zurückgegeben werden. Um dies zu bestätigen, fügen Sie der Seite eine GridView hinzu, binden Sie sie an diese Datenquelle, und zeigen Sie die Seite dann über einen Browser an. Sie sollten nur die Produkte sehen, die weniger als oder gleich 25,00 $ sind, wie in Abbildung 3 bestätigt wird.
Abbildung 3: Nur diese Produkte, die kleiner oder gleich 25,00 $ 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 kleiner als ein bestimmter Schwellenwert sind. Fügen Sie der ParameterizedQueries.aspx
Seite zunächst ein Textfeld hinzu, um diesen Schwellenwert vom Benutzer zu erfassen. Legen Sie die Eigenschaft der TextBox ID
auf MaxPrice
fest. Fügen Sie ein Schaltflächenweb-Steuerelement hinzu, und legen Sie dessen Text
Eigenschaft auf "Übereinstimmende Produkte anzeigen" fest.
Ziehen Sie als Nächstes ein GridView-Steuerelement auf die Seite, und wählen Sie im Smart Tag die Option zum Erstellen einer neuen SqlDataSource namens ProductsFilteredByPriceDataSource
. Im Assistenten "Datenquelle konfigurieren" fahren Sie mit der Seite "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".
Abbildung 4: Nur die Produkte zurückgeben, die kleiner oder gleich einem Parameterwert sind (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Da die Abfrage Parameter enthält, fordert der nächste Bildschirm im Assistenten uns zur Quelle der Parameterwerte auf. Wählen Sie "Control" aus der Dropdown-Liste für die Parameterquelle und MaxPrice
(den Wert des TextBox-Controls ID
) aus der Dropdown-Liste für die ControlID. Sie können auch einen optionalen Standardwert eingeben, der verwendet werden soll, wenn der Benutzer keinen Text in das MaxPrice
Textfeld eingegeben hat. Geben Sie vorerst keinen Standardwert ein.
Abbildung 5: Die MaxPrice
TextBox-Eigenschaft Text
wird als Parameterquelle verwendet (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Schließen Sie den Assistenten zum Konfigurieren der Datenquelle ab, indem Sie auf "Weiter" und anschließend 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 "SqlDataSource" <SelectParameters>
ein ControlParameter
ist, der zusätzliche Eigenschaften wie ControlID
und PropertyName
umfasst. Wenn die Methode Select()
der SqlDataSource aufgerufen wird, holt ControlParameter
den Wert aus der angegebenen Eigenschaft des Websteuerelements und weist ihn dem entsprechenden Parameter in SelectCommand
zu. In diesem Beispiel wird die MaxPrice
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 das MaxPrice
TextBox-Objekt keinen Wert aufweist, werden keine Datensätze in gridView angezeigt.
Abbildung 6: Es werden keine Datensätze angezeigt, wenn das MaxPrice
Textfeld leer ist (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Der Grund, warum keine Produkte angezeigt werden, ist, dass standardmäßig eine leere Zeichenfolge für einen Parameterwert in einen Datenbankwert NULL
konvertiert wird. Da der Vergleich von [UnitPrice] <= NULL
immer als falsch ausgewertet wird, werden keine Ergebnisse zurückgegeben.
Geben Sie einen Wert in das Textfeld ein, z. B. 5,00, und klicken Sie auf die Schaltfläche "Übereinstimmende Produkte anzeigen". Bei einem Postback informiert die SqlDataSource die GridView darüber, dass eine ihrer Parameterquellen geändert wurde. Folglich wird die GridView erneut mit der SqlDataSource verbunden und zeigt jene Produkte an, die weniger als oder gleich 5,00 $ kosten.
Abbildung 7: Produkte, die kleiner als oder gleich 5,00 $ sind, werden angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Anfängliches Anzeigen aller Produkte
Anstatt beim ersten Laden der Seite keine Produkte anzuzeigen, möchten wir möglicherweise alle Produkte anzeigen. Eine Möglichkeit zum Auflisten aller Produkte, wenn das MaxPrice
TextBox-Objekt leer ist, besteht darin, den Standardwert des Parameters auf einen unsinnig hohen Wert festzulegen, z. B. 1000000, da es unwahrscheinlich ist, dass Northwind Traders jemals über Lagerbestände verfügen, deren Einzelpreis 1.000.000 $ überschreitet. Dieser Ansatz ist jedoch kurzsichtig und funktioniert in anderen Situationen möglicherweise nicht.
In früheren Lernprogrammen – Deklarative Parameter und Master/Detail-Filterung mit einem DropDownList-Element waren wir mit einem ähnlichen Problem konfrontiert. Unsere Lösung bestand darin, diese Logik in die Geschäftslogikebene zu setzen. Insbesondere untersuchte die BLL den eingehenden Wert, und wenn er NULL
oder ein reservierter Wert war, 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 ausgeführt, die eine SQL-Anweisung ausgeführt hat, die eine parametrisierte WHERE
Klausel mit dem angegebenen Wert verwendet hat.
Leider umgehen wir die Architektur bei Verwendung von SqlDataSource. Stattdessen müssen wir die SQL-Anweisung so anpassen, dass alle Datensätze intelligent abgerufen werden, 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.0
ist, alle Datensätze zurückgegeben werden sollen (-1.0
funktioniert als reservierter Wert, da kein Produkt einen negativen UnitPrice
Wert haben kann). Dazu 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.0
ist, werden nur die Produkte zurückgegeben, deren UnitPrice
Wert kleiner oder gleich dem @MaximumPrice
Parameterwert ist. Durch Festlegen des Standardwerts des @MaximumPrice
-Parameters auf -1.0
erhält MaxPrice
beim ersten Laden der Seite (oder wenn die @MaximumPrice
TextBox leer ist) den Wert -1.0
, und alle Produkte werden angezeigt.
Abbildung 8: Jetzt werden alle Produkte angezeigt, wenn das MaxPrice
Textfeld leer ist (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Es gibt ein paar Vorbehalte, die mit diesem Ansatz zu beachten sind. Stellen Sie zunächst fest, dass der Datentyp des Parameters von der Verwendung in der SQL-Abfrage abgeleitet wird. Wenn Sie die WHERE
Klausel von @MaximumPrice = -1.0
auf @MaximumPrice = -1
ändern, behandelt die Laufzeitumgebung den Parameter als ganze Zahl. Wenn Sie dann versuchen, das MaxPrice
TextBox-Objekt 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 @MaximumPrice = -1.0
in der WHERE
-Klausel verwenden oder, besser noch, die Eigenschaft des ControlParameter
-Objekts Type
auf Dezimal festlegen.
Zweitens kann die Abfrage-Engine durch die Aufnahme von OR @MaximumPrice = -1.0
in die WHERE
Klausel keinen Index auf UnitPrice
verwenden, falls dieser existiert, wodurch ein Tabellenscan entsteht. Dies kann sich auf die Leistung auswirken, wenn eine ausreichend große Anzahl von Datensätzen in der Products
Tabelle vorhanden ist. Ein besserer Ansatz wäre das Verschieben dieser Logik in eine gespeicherte Prozedur, bei der eine IF
Anweisung entweder eine SELECT
Abfrage aus der Products
Tabelle ohne WHERE
Klausel ausführt, wenn alle Datensätze zurückgegeben werden müssen oder eine Klausel, 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 in der gespeicherten Prozedur definierten SQL-Anweisungen verwendet werden können. Beim Konfigurieren der SqlDataSource für die Verwendung einer gespeicherten Prozedur, die Eingabeparameter akzeptiert, können diese Parameterwerte mit denselben Techniken wie bei 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 namens GetProductsByCategory
, die einen Parameter namens @CategoryID
akzeptiert und alle Spalten der Produkte zurückgibt, deren CategoryID
Spalten übereinstimmen @CategoryID
. Um eine gespeicherte Prozedur zu erstellen, wechseln Sie zum Server-Explorer, und führen Sie einen Drilldown in die NORTHWND.MDF
Datenbank durch. (Wenn der 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 Datenbank mit der NORTHWND.MDF
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 aufgefordert, die Parameter der gespeicherten Prozedur (@CategoryID
in dieser Instanz) einzugeben, nach der die Ergebnisse im Ausgabefenster angezeigt werden.
Abbildung 9: Die GetProductsByCategory
gespeicherte Prozedur, wenn sie mit einer @CategoryID
von 1 ausgeführt wird (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Lassen Sie uns dieses gespeicherte Verfahren verwenden, 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 "Angeben einer benutzerdefinierten SQL-Anweisung oder gespeicherten Prozedur" fort, wählen Sie das Optionsfeld "Gespeicherte Prozedur" aus, und wählen Sie die GetProductsByCategory
gespeicherte Prozedur aus der Dropdownliste aus.
Abbildung 10: Auswählen der GetProductsByCategory
gespeicherten Prozedur aus der liste Drop-Down (Klicken Sie hier, um das Bild mit voller Größe anzuzeigen)
Da die gespeicherte Prozedur einen Eingabeparameter akzeptiert (@CategoryID
), führt uns durch Klicken auf "Weiter" dazu, die Quelle für den Wert dieses Parameters anzugeben. Die Getränke CategoryID
sind 1, lassen Sie also die Dropdownliste "Parameterquelle" bei "None" und geben Sie "1" in das Textfeld "DefaultValue" ein.
Abbildung 11: Verwenden eines Hard-Coded Werts von 1, um die Produkte in der Kategorie "Getränke" zurückzugeben (Klicken Sie hier, um das Bild mit 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 festgelegt, und die SelectCommandType
Eigenschaft wird auf festgelegt StoredProcedure
, wobei angegeben wird, dass es sich SelectCommand
um den Namen einer gespeicherten Prozedur anstelle einer Ad-hoc-SQL-Anweisung handelt.
<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. Nur die Produkte, die zur Kategorie "Getränke" gehören, werden angezeigt, obwohl alle Produktfelder angezeigt werden, da die GetProductsByCategory
gespeicherte Prozedur alle Spalten aus der Products
Tabelle zurückgibt. Natürlich können wir die felder einschränken oder anpassen, die im GridView-Dialogfeld "Spalten bearbeiten" angezeigt werden.
Abbildung 12: Alle Getränke werden angezeigt (Zum Anzeigen des Bilds mit voller Größe klicken)
Schritt 4: Programmgesteuertes Aufrufen der Select() -Anweisung einer SqlDataSource
Die Beispiele, die wir im vorherigen Lernprogramm und bisher in diesem Lernprogramm gesehen haben, haben SqlDataSource-Steuerelemente direkt an ein GridView gebunden. Auf die Daten des SqlDataSource-Steuerelements kann jedoch programmgesteuert zugegriffen und im Quellcode aufgezählt werden. Dies kann besonders nützlich sein, wenn Sie Daten abfragen müssen, um sie zu prüfen, aber nicht anzeigen müssen. Anstatt den gesamten Textbaustein ADO.NET Code schreiben zu müssen, um eine Verbindung mit der Datenbank herzustellen, den Befehl anzugeben und die Ergebnisse abzurufen, können Sie die SqlDataSource diesen monotonen Code behandeln lassen.
Um die programmgesteuerte Arbeit mit den SqlDataSource-Daten zu veranschaulichen, stellen Sie sich vor, dass Ihr Vorgesetzter Sie mit einer Anforderung zum Erstellen einer Webseite angegangen hat, die den Namen einer zufällig ausgewählten Kategorie und der zugehörigen Produkte anzeigt. Das heißt, wenn ein Benutzer diese Seite besucht, möchten wir zufällig 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, um eine zufällige Kategorie aus der Categories
Tabelle und eine andere abzurufen, um die Produkte der Kategorie abzurufen. Wir erstellen die SqlDataSource, die in diesem Schritt einen zufälligen Kategoriedatensatz abruft. Schritt 5 befasst sich mit dem Erstellen der SqlDataSource, die die Produkte der Kategorie abruft.
Fügen Sie zunächst eine SqlDataSource zu ParameterizedQueries.aspx
hinzu und legen Sie ihre Eigenschaft ID
auf RandomCategoryDataSource
fest. Konfigurieren Sie sie so, dass sie die folgende SQL-Abfrage verwendet:
SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()
ORDER BY NEWID()
gibt die datensätze in zufälliger Reihenfolge sortiert zurück (siehe Verwenden NEWID()
zur zufälligen Sortierung von Datensätzen).
SELECT TOP 1
gibt den ersten Datensatz aus dem Resultset zurück. Diese Abfrage gibt die Spaltenwerte von CategoryID
und CategoryName
aus einer einzelnen, zufällig ausgewählten Kategorie zurück.
Wenn Sie den Wert der Kategorie CategoryName
anzeigen möchten, fügen Sie der Seite ein Websteuerelement vom Typ 'Label' hinzu, legen Sie dessen ID
Eigenschaft auf CategoryNameLabel
fest, und löschen Sie dessen Text
Eigenschaft. Um die Daten programmgesteuert aus einem SqlDataSource-Steuerelement abzurufen, müssen wir seine Select()
Methode aufrufen. Die Select()
Methode erwartet einen einzelnen Eingabeparameter vom Typ DataSourceSelectArguments
, der angibt, wie die Daten vor der Rückgabe angezeigt werden sollen. Dies kann Anweisungen zum Sortieren und Filtern der Daten enthalten und wird von den Datenwebsteuerelementen beim Sortieren oder Ausblättern der Daten aus einem SqlDataSource-Steuerelement verwendet. In unserem Beispiel müssen die Daten jedoch nicht geändert werden, bevor sie zurückgegeben werden. Daher wird das DataSourceSelectArguments.Empty
Objekt übergeben.
Die Select()
Methode gibt ein Objekt zurück, das IEnumerable
implementiert. Der zurückgegebene genaue Typ hängt vom Wert der Eigenschaft des SqlDataSource-Steuerelements DataSourceMode
ab. Wie im vorherigen Tutorial erläutert, kann diese Eigenschaft entweder auf einen Wert von DataSet
oder DataReader
gesetzt werden. Bei Festlegung auf DataSet
, gibt die Select()
Methode ein DataView -Objekt zurück; wenn festgelegt auf DataReader
, wird ein Objekt zurückgegeben, das implementiert IDataReader
wird. Da die SqlDataSource ihre RandomCategoryDataSource
-Eigenschaft auf DataSourceMode
(der Standardeinstellung) gesetzt hat, werden wir mit einem DataView-Objekt arbeiten.
Der folgende Code veranschaulicht, wie die Datensätze aus der RandomCategoryDataSource
SqlDataSource als DataView abgerufen 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 das 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 DataView schwach typisiert ist. Um auf einen bestimmten Spaltenwert zu verweisen, müssen wir den Namen der Spalte als Zeichenfolge übergeben ( CategoryName, in diesem Fall). Abbildung 13 zeigt die Meldung, die CategoryNameLabel
beim Anzeigen der Seite angezeigt wird. Natürlich wird der angezeigte Kategoriename zufällig ausgewählt von der RandomCategoryDataSource
SqlDataSource bei jedem Besuch der Seite, einschließlich Postbacks.
Abbildung 13: Der Name der zufällig ausgewählten Kategorie wird angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Hinweis
Wenn die Eigenschaft des SqlDataSource-Steuerelements DataSourceMode
auf DataReader
festgelegt worden wäre, müsste der Rückgabewert aus der Select()
-Methode in IDataReader
umgewandelt werden. Um den CategoryName
Spaltenwert aus der ersten Zeile zu lesen, verwenden wir Code wie folgt:
if (randomCategoryReader.Read())
{
string categoryName = randomCategoryReader["CategoryName"].ToString();
...
}
Wenn SqlDataSource eine Kategorie zufällig auswählt, können wir die GridView hinzufügen, die die Produkte der Kategorie auflistet.
Hinweis
Anstatt ein Label-Webkontrollelement zum Anzeigen des Kategorienamens zu verwenden, hätten wir der Seite eine FormView oder DetailsView hinzufügen und an die SqlDataSource binden können. 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 Lernprogramm gesehen haben, haben entweder einen hartcodierten Parameterwert oder einen 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. Zum Abschließen des aktuellen Beispiels 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
von der RandomCategoryDataSource
SqlDataSource im Page_Load
Ereignishandler zurückgegebenen Spaltenwert festgelegt werden muss.
Beginnen Sie, indem Sie der Seite eine GridView hinzufügen und an eine neue SqlDataSource mit dem Namen ProductsByCategoryDataSource
binden. Ähnlich wie in Schritt 3 konfigurieren Sie die SqlDataSource so, dass sie die GetProductsByCategory
gespeicherte Prozedur aufruft. Lassen Sie die Dropdownliste "Parameterquelle" auf "Keine" festgelegt, geben Sie jedoch keinen Standardwert ein, da wir diesen Standardwert programmgesteuert festlegen.
Abbildung 14: Keine Parameterquelle oder keinen Standardwert angeben (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nach Abschluss des SqlDataSource-Assistenten sollte das resultierende deklarative Markup ähnlich 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
-Parameter des CategoryID
programmgesteuert im Ereignishandler des Page_Load
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.
Abbildung 15: Keine Parameterquelle oder keinen Standardwert angeben (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 Lernprogramm haben wir erfahren, wie Sie eine parametrisierte Abfrage aus dem Assistenten zum Konfigurieren von Datenquellen für Ad-hoc-SQL-Abfragen und gespeicherte Prozeduren erstellen. Außerdem haben wir die Verwendung hartcodierter Parameterquellen, eines Websteuerelements als Parameterquelle und die programmgesteuerte Angabe des Parameterwerts untersucht.
Wie bei objectDataSource bietet die SqlDataSource auch Funktionen zum Ändern der zugrunde liegenden Daten. Im nächsten Lernprogramm werden wir uns damit befassen, wie man INSERT
, UPDATE
, und DELETE
-Anweisungen mit dem SqlDataSource definiert. Nachdem diese Anweisungen hinzugefügt wurden, können wir die integrierten Einfüge-, Bearbeitungs- und Löschfunktionen verwenden, die den GridView-, DetailsView- und FormView-Steuerelementen inhärent sind.
Glückliche Programmierung!
Zum Autor
Scott Mitchell, Autor von sieben ASP/ASP.NET Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft Web Technologies zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann bei mitchell@4GuysFromRolla.comerreicht werden.
Besonderer Dank an
Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Scott Clyde, Randell Schmidt und Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn ja, schicken Sie mir eine Nachricht an mitchell@4GuysFromRolla.com.