Freigeben über


Datenquellensteuerelemente

von Microsoft

Das DataGrid-Steuerelement in ASP.NET 1.x hat eine große Verbesserung des Datenzugriffs in Webanwendungen markiert. Es war jedoch nicht so benutzerfreundlich wie es gewesen sein könnte. Es war noch eine beträchtliche Menge code erforderlich, um viel nützliche Funktionen daraus zu erhalten. Dies ist das Modell in allen Datenzugriffsbemühungen in 1.x.

Das DataGrid-Steuerelement in ASP.NET 1.x hat eine große Verbesserung des Datenzugriffs in Webanwendungen markiert. Es war jedoch nicht so benutzerfreundlich wie es gewesen sein könnte. Es war noch eine beträchtliche Menge code erforderlich, um viel nützliche Funktionen daraus zu erhalten. Dies ist das Modell in allen Datenzugriffsbemühungen in 1.x.

ASP.NET 2.0 behebt dies teilweise mit Datenquellensteuerelementen. Die Datenquellensteuerelemente in ASP.NET 2.0 bieten Entwicklern ein deklaratives Modell zum Abrufen von Daten, zum Anzeigen von Daten und zum Bearbeiten von Daten. Der Zweck von Datenquellensteuerelementen besteht darin, unabhängig von der Quelle dieser Daten eine konsistente Darstellung von Daten für datengebundene Steuerelemente bereitzustellen. Das Herzstück der Datenquellensteuerelemente in ASP.NET 2.0 ist die abstrakte DataSourceControl-Klasse. Die DataSourceControl-Klasse stellt eine Basisimplementierung der IDataSource-Schnittstelle und der IListSource-Schnittstelle bereit, von der aus Sie das Datenquellensteuerelement als Datenquelle eines datengebundenen Steuerelements (über die zu einem späteren Zeitpunkt erläuterte neue DataSourceId-Eigenschaft) zuweisen und die Daten dort als Liste verfügbar machen können. Jede Liste der Daten aus einem Datenquellensteuerelement wird als DataSourceView-Objekt verfügbar gemacht. Der Zugriff auf die DataSourceView-Instanzen wird von der IDataSource-Schnittstelle bereitgestellt. Beispielsweise gibt die GetViewNames-Methode eine ICollection zurück, mit der Sie die DataSourceViews aufzählen können, die einem bestimmten Datenquellensteuerelement zugeordnet sind, und mit der GetView-Methode können Sie nach Namen auf eine bestimmte DataSourceView-Instanz zugreifen.

Datenquellensteuerelemente haben keine Benutzeroberfläche. Sie werden als Serversteuerelemente implementiert, damit sie deklarative Syntax unterstützen und bei Bedarf Zugriff auf den Seitenstatus haben. Datenquellensteuerelemente rendern kein HTML-Markup für den Client.

Hinweis

Wie Sie später sehen werden, gibt es auch Zwischenspeicherungsvorteile, die mithilfe von Datenquellensteuerelementen erzielt werden.

Speichern von Verbindungszeichenfolgen

Bevor wir uns ansehen, wie Datenquellensteuerelemente konfiguriert werden, sollten wir eine neue Funktion in ASP.NET 2.0 bezüglich Verbindungszeichenfolgen abdecken. ASP.NET 2.0 führt einen neuen Abschnitt in der Konfigurationsdatei ein, mit dem Sie Verbindungszeichenfolgen problemlos speichern können, die zur Laufzeit dynamisch gelesen werden können. Der <Abschnitt "connectionStrings> " erleichtert das Speichern von Verbindungszeichenfolgen.

Der folgende Codeausschnitt fügt eine neue Verbindungszeichenfolge hinzu.

<connectionStrings> <add name="Northwind" connectionString="Data Source=localhost; Integrated Security=SSPI;Initial Catalog=Northwind;" providerName="System.Data.SqlClient" /> </connectionStrings>

Hinweis

Genau wie beim <Abschnitt "appSettings>" wird der <Abschnitt "connectionStrings" außerhalb des >Abschnitts< "system.web>" in der Konfigurationsdatei angezeigt.

Um diese Verbindungszeichenfolge zu verwenden, können Sie beim Festlegen des ConnectionString-Attributs eines Serversteuerelements die folgende Syntax verwenden.

ConnectionString="<%$ ConnectionStrings:Northwind%>"

Der <Abschnitt "connectionStrings"> kann auch verschlüsselt werden, sodass vertrauliche Informationen nicht verfügbar gemacht werden. Diese Fähigkeit wird in einem späteren Modul behandelt.

Zwischenspeichern von Datenquellen

Jedes DataSourceControl stellt vier Eigenschaften zum Konfigurieren der Zwischenspeicherung bereit; EnableCaching, CacheDuration, CacheExpirationPolicy und CacheKeyDependency.

EnableCaching

EnableCaching ist eine boolesche Eigenschaft, die bestimmt, ob das Zwischenspeichern für das Datenquellensteuerelement aktiviert ist.

CacheDuration-Eigenschaft

Die CacheDuration-Eigenschaft legt die Anzahl der Sekunden fest, die der Cache gültig bleibt. Wenn Sie diese Eigenschaft auf 0 festlegen, bleibt der Cache gültig, bis er explizit ungültig wurde.

CacheExpirationPolicy-Eigenschaft

Die CacheExpirationPolicy-Eigenschaft kann entweder auf Absolute oder Sliding festgelegt werden. Das Festlegen auf "Absolut" bedeutet, dass die maximale Zeitspanne, die die Daten zwischengespeichert werden, die Anzahl der Sekunden ist, die von der CacheDuration-Eigenschaft angegeben werden. Wenn es auf "Sliding" eingestellt wird, wird die Ablaufzeit zurückgesetzt, sobald jede Operation ausgeführt wird.

CacheKeyDependency-Eigenschaft

Wenn für die CacheKeyDependency-Eigenschaft ein Zeichenfolgenwert angegeben wird, richtet ASP.NET basierend auf dieser Zeichenfolge eine neue Cacheabhängigkeit ein. Auf diese Weise können Sie den Cache explizit ungültig machen, indem Sie einfach die CacheKeyDependency ändern oder entfernen.

Wichtig: Wenn der Identitätswechsel aktiviert ist und der Zugriff auf die Datenquelle und/oder den Dateninhalt auf der Client-Identität basiert, empfiehlt es sich, das Zwischenspeichern zu deaktivieren, indem "EnableCaching" auf False gesetzt wird. Wenn die Zwischenspeicherung in diesem Szenario aktiviert ist und ein anderer Benutzer als der Benutzer, der die Daten ursprünglich angefordert hat, eine Anforderung ausgibt, wird die Autorisierung für die Datenquelle nicht erzwungen. Die Daten werden einfach aus dem Cache bereitgestellt.

Das SqlDataSource-Steuerelement

Mit dem SqlDataSource-Steuerelement kann ein Entwickler auf Daten zugreifen, die in jeder relationalen Datenbank gespeichert sind, die ADO.NET unterstützt. Sie kann den System.Data.SqlClient-Anbieter verwenden, um auf eine SQL Server-Datenbank, den System.Data.OleDb-Anbieter, den System.Data.Odbc-Anbieter oder den System.Data.OracleClient-Anbieter zuzugreifen, um auf Oracle zuzugreifen. Daher wird die SqlDataSource sicherlich nicht nur für den Zugriff auf Daten in einer SQL Server-Datenbank verwendet.

Um sqlDataSource zu verwenden, geben Sie einfach einen Wert für die ConnectionString-Eigenschaft an und geben einen SQL-Befehl oder eine gespeicherte Prozedur an. Das SqlDataSource-Steuerelement kümmert sich um die Arbeit mit der zugrunde liegenden ADO.NET Architektur. Sie öffnet die Verbindung, fragt die Datenquelle ab oder führt die gespeicherte Prozedur aus, gibt die Daten zurück und schließt dann die Verbindung für Sie.

Hinweis

Da die DataSourceControl-Klasse die Verbindung für Sie automatisch schließt, sollte die Anzahl der Anrufe von Kunden reduziert werden, die durch den Verlust von Datenbankverbindungen generiert werden.

Der folgende Codeausschnitt bindet ein DropDownList-Steuerelement an ein SqlDataSource-Steuerelement mithilfe der Verbindungszeichenfolge, die in der Konfigurationsdatei gespeichert ist, wie oben gezeigt.

<asp:SqlDataSource id="SqlDataSource1" runat="server" DataSourceMode="DataReader" ConnectionString="<%$ ConnectionStrings:Northwind%>" SelectCommand="SELECT EmployeeID, LastName FROM Employees"> </asp:SqlDataSource><asp:DropDownList id="ListBox1" runat="server" DataTextField="LastName" DataValueField="EmployeeID" DataSourceID="SqlDataSource1"> </asp:DropDownList>

Wie oben dargestellt, gibt die DataSourceMode-Eigenschaft der SqlDataSource den Modus für die Datenquelle an. Im obigen Beispiel wird "DataSourceMode" auf "DataReader" festgelegt. In diesem Fall gibt die SqlDataSource ein IDataReader-Objekt mit einem nur-vorwärts und nur-lesenden Cursor zurück. Der angegebene Objekttyp, der zurückgegeben wird, wird vom verwendeten Anbieter gesteuert. In diesem Fall verwende ich den System.Data.SqlClient-Anbieter, wie im <Abschnitt "connectionStrings> " der datei web.config angegeben. Daher weist das zurückgegebene Objekt den Typ SqlDataReader auf. Durch Angeben eines DataSourceMode-Werts von DataSet können die Daten in einem DataSet auf dem Server gespeichert werden. Mit diesem Modus können Sie Funktionen wie Sortieren, Seitennummerierung hinzufügen. Wenn ich die SqlDataSource an ein GridView-Steuerelement gebunden hätte, hätte ich den DataSet-Modus ausgewählt. Im Fall einer DropDownList ist der DataReader-Modus jedoch die richtige Wahl.

Hinweis

Beim Zwischenspeichern einer SqlDataSource oder einer AccessDataSource muss die DataSourceMode-Eigenschaft auf DataSet festgelegt werden. Eine Ausnahme tritt auf, wenn Sie die Zwischenspeicherung mit einem DataSourceMode von DataReader aktivieren.

SqlDataSource-Eigenschaften

Im Folgenden sind einige der Eigenschaften des SqlDataSource-Steuerelements aufgeführt.

AbbrechenAuswahlBeiNullParameter

Ein boolescher Wert, der angibt, ob ein Auswahlbefehl abgebrochen wird, wenn einer der Parameter null ist. Wahr standardmäßig.

Konflikterkennung

In einer Situation, in der mehrere Benutzer gleichzeitig eine Datenquelle aktualisieren, bestimmt die ConflictDetection-Eigenschaft das Verhalten des SqlDataSource-Steuerelements. Diese Eigenschaft wird zu einem der Werte der ConflictOptions-Aufzählung ausgewertet. Diese Werte sind CompareAllValues und OverwriteChanges. Wenn diese Eigenschaft auf OverwriteChanges festgelegt ist, überschreibt die letzte Person, die Daten in die Datenquelle schreibt, alle vorherigen Änderungen. Wenn die ConflictDetection-Eigenschaft jedoch auf CompareAllValues festgelegt ist, werden Parameter für die spalten erstellt, die vom SelectCommand zurückgegeben werden, und Parameter werden auch erstellt, um die ursprünglichen Werte in jeder dieser Spalten zu enthalten, sodass die SqlDataSource bestimmen kann, ob sich die Werte seit der Ausführung von SelectCommand geändert haben.

Delete-Befehl

Legt die SQL-Zeichenfolge fest, die beim Löschen von Zeilen aus der Datenbank verwendet wird, oder ruft sie ab. Dies kann entweder eine SQL-Abfrage oder ein Name einer gespeicherten Prozedur sein.

DeleteCommandType

Legt fest oder ruft den Typ des Löschbefehls, entweder eine SQL-Abfrage (Text) oder eine gespeicherte Prozedur (StoredProcedure).

Deleteparameters

Gibt die Parameter zurück, die vom DeleteCommand des SqlDataSourceView -Objekts verwendet werden, das dem SqlDataSource -Steuerelement zugeordnet ist.

OldValuesParameterFormatString

Diese Eigenschaft wird verwendet, um das Format der ursprünglichen Wertparameter in Fällen anzugeben, in denen die ConflictDetection-Eigenschaft auf CompareAllValues festgelegt ist. Der Standard ist {0}, was bedeutet, dass ursprüngliche Wertparameter denselben Namen wie der ursprüngliche Parameter erhalten. Anders ausgedrückt: Wenn der Feldname "EmployeeID" lautet, lautet @EmployeeIDder ursprüngliche Wertparameter .

SelectCommand

Legt die SQL-Zeichenfolge fest, die zum Abrufen von Daten aus der Datenbank verwendet wird, oder ruft diese ab. Dies kann entweder eine SQL-Abfrage oder ein Name einer gespeicherten Prozedur sein.

SelectCommandType

Legt fest oder ruft den Typ des Auswahlbefehls, entweder eine SQL-Abfrage (Text) oder eine gespeicherte Prozedur (StoredProcedure).

SelectParameters

Gibt die Parameter zurück, die vom SelectCommand des SqlDataSourceView -Objekts verwendet werden, das dem SqlDataSource -Steuerelement zugeordnet ist.

Sortierparametername

Dient zum Abrufen oder Festlegen des Namens eines gespeicherten Prozedurparameters, der beim Sortieren von Daten verwendet wird, die vom Datenquellensteuerelement abgerufen werden. Nur gültig, wenn SelectCommandType auf StoredProcedure festgelegt ist.

Sqlcachedependency

Eine durch Semikolons getrennte Zeichenfolge, die die Datenbanken und Tabellen angibt, die in einer SQL Server-Cacheabhängigkeit verwendet werden. (SQL-Cacheabhängigkeiten werden in einem späteren Modul erläutert.)

Update-Befehl

Legt die SQL-Zeichenfolge fest, die beim Aktualisieren von Daten in der Datenbank verwendet wird, oder ruft diese ab. Dies kann entweder eine SQL-Abfrage oder ein Name einer gespeicherten Prozedur sein.

UpdateBefehlstyp

Legt fest oder ruft den Typ des Aktualisierungsbefehls, entweder eine SQL-Abfrage (Text) oder eine gespeicherte Prozedur (StoredProcedure).

UpdateParameters

Gibt die Parameter zurück, die vom UpdateCommand des SqlDataSourceView -Objekts verwendet werden, das dem SqlDataSource -Steuerelement zugeordnet ist.

Das AccessDataSource-Steuerelement

Das AccessDataSource-Steuerelement wird von der SqlDataSource-Klasse abgeleitet und verwendet, um eine Datenbindung an eine Microsoft Access-Datenbank auszuführen. Die ConnectionString-Eigenschaft für das AccessDataSource-Steuerelement ist eine schreibgeschützte Eigenschaft. Anstatt die ConnectionString-Eigenschaft zu verwenden, wird die DataFile-Eigenschaft verwendet, um wie unten dargestellt auf die Access-Datenbank zu verweisen.

<asp:AccessDataSource id="AccessDataSource1" runat="server" DataFile="~/App_Data/Northwind.mdb"> </asp:AccessDataSource>

AccessDataSource legt immer den ProviderName der SqlDataSource-Basis auf System.Data.OleDb fest und stellt über den OLE DB-Anbieter Microsoft.Jet.OLEDB.4.0 eine Verbindung zur Datenbank her. Sie können das AccessDataSource-Steuerelement nicht verwenden, um eine Verbindung mit einer kennwortgeschützten Access-Datenbank herzustellen. Wenn Sie eine Verbindung mit einer kennwortgeschützten Datenbank herstellen müssen, sollten Sie das SqlDataSource-Steuerelement verwenden.

Hinweis

Zugriffsdatenbanken, die auf der Website gespeichert sind, sollten im verzeichnis App_Data platziert werden. ASP.NET lässt das Durchsuchen von Dateien in diesem Verzeichnis nicht zu. Sie müssen dem Prozesskonto Lese- und Schreibberechtigungen für das verzeichnis App_Data erteilen, wenn Sie Access-Datenbanken verwenden.

XmlDataSource-Steuerelement

Die XmlDataSource wird verwendet, um XML-Daten an datengebundene Steuerelemente zu binden. Sie können eine Bindung an eine XML-Datei mithilfe der DataFile-Eigenschaft oder eine Bindung an eine XML-Zeichenfolge mithilfe der Data-Eigenschaft herstellen. Die XmlDataSource macht XML-Attribute als bindungsfähige Felder verfügbar. In Fällen, in denen Sie eine Bindung an Werte ausführen müssen, die nicht als Attribute dargestellt werden, müssen Sie eine XSL-Transformation verwenden. Sie können XPath-Ausdrücke auch verwenden, um XML-Daten zu filtern.

Betrachten Sie die folgende XML-Datei:

<?xml version="1.0" encoding="utf-8" ?> <People> <Person FirstName="Jake" LastName="Stone"> <Address> <Street>345 Maple St.</Street> <City>Redmond</City> <Region>WA</Region> <ZipCode>01434</ZipCode> </Address> <Job> <Title>CEO</Title> <Description>Develops company strategies.</Description> </Job> </Person> <Person FirstName="Jacob" LastName="Ladder"> <Address> <Street>123 Elm St.</Street> <City>Seattle</City> <Region>WA</Region> <ZipCode>11223</ZipCode> </Address> <Job> <Title>Attorney</Title> <Description>Reviews legal issues.</Description> </Job> </Person> <Person FirstName="Angela" LastName="Hound"> <Address> <Street>34 Palm Avenue</Street> <City>Renton</City> <Region>WA</Region> <ZipCode>63910</ZipCode> </Address> <Job> <Title>IT Director</Title> <Description>In charge of corporate network.</Description> </Job> </Person> </People>

Beachten Sie, dass die XmlDataSource eine XPath-Eigenschaft von People/Person verwendet, um nur nach den <Person-Knoten> zu filtern. Die DropDownList bindet dann Daten an das LastName-Attribut mithilfe der DataTextField-Eigenschaft.

Während das XmlDataSource-Steuerelement in erster Linie zur Datenbindung an schreibgeschützte XML-Daten verwendet wird, kann die XML-Datendatei auch bearbeitet werden. Beachten Sie, dass in solchen Fällen das automatische Einfügen, Aktualisieren und Löschen von Informationen in der XML-Datei nicht automatisch erfolgt, wie es mit anderen Datenquellensteuerelementen der Fall ist. Stattdessen müssen Sie Code schreiben, um die Daten mithilfe der folgenden Methoden des XmlDataSource-Steuerelements manuell zu bearbeiten.

GetXmlDocument

Ruft ein XmlDocument -Objekt ab, das den XML-Code enthält, der von der XmlDataSource abgerufen wird.

Speichern

Speichert das in-memory XmlDocument zurück in die Datenquelle.

Es ist wichtig zu erkennen, dass die Save-Methode nur funktioniert, wenn die folgenden beiden Bedingungen erfüllt sind:

  1. Die XmlDataSource verwendet die DataFile-Eigenschaft zum Binden an eine XML-Datei anstelle der Data-Eigenschaft, um eine Bindung an XML-Daten im Arbeitsspeicher herzustellen.
  2. Es wird keine Transformation über die Transform- oder TransformFile-Eigenschaft angegeben.

Beachten Sie auch, dass die Save-Methode unerwartete Ergebnisse liefern kann, wenn sie von mehreren Benutzern gleichzeitig aufgerufen werden.

Das ObjectDataSource-Steuerelement

Die Datenquellensteuerelemente, die wir an diesem Punkt behandelt haben, sind hervorragende Auswahlmöglichkeiten für zweistufige Anwendungen, bei denen das Datenquellensteuerelement direkt mit dem Datenspeicher kommuniziert. Viele reale Anwendungen sind jedoch mehrstufige Anwendungen, bei denen ein Datenquellensteuerelement möglicherweise mit einem Geschäftsobjekt kommunizieren muss, das wiederum mit der Datenschicht kommuniziert. In diesen Fällen füllt ObjectDataSource die Rechnung gut aus. Die ObjectDataSource funktioniert in Verbindung mit einem Quellobjekt. Das ObjectDataSource-Steuerelement erstellt eine Instanz des Quellobjekts, ruft die angegebene Methode auf und verwirft die Objektinstanz - alles innerhalb des Bereichs einer einzelnen Anfrage -, wenn Ihr Objekt Instanzmethoden anstelle statischer Methoden (Shared in Visual Basic) verwendet. Daher muss Ihr Objekt zustandslos sein. Das heißt, Ihr Objekt sollte alle erforderlichen Ressourcen innerhalb einer einzelnen Anforderung abrufen und freigeben. Sie können steuern, wie das Quellobjekt erstellt wird, indem Sie das ObjectCreating-Ereignis des ObjectDataSource-Steuerelements behandeln. Sie können eine Instanz des Quellobjekts erstellen und dann die ObjectInstance-Eigenschaft der ObjectDataSourceEventArgs-Klasse auf diese Instanz festlegen. Das ObjectDataSource-Steuerelement verwendet die Instanz, die im ObjectCreating-Ereignis erstellt wird, anstatt eine Instanz eigenständig zu erstellen.

Wenn das Quellobjekt für ein ObjectDataSource-Steuerelement öffentliche statische Methoden (Shared in Visual Basic) verfügbar macht, die aufgerufen werden können, um Daten abzurufen und zu ändern, ruft ein ObjectDataSource-Steuerelement diese Methoden direkt auf. Wenn ein ObjectDataSource-Steuerelement eine Instanz des Quellobjekts erstellen muss, um Methodenaufrufe ausführen zu können, muss das Objekt einen öffentlichen Konstruktor enthalten, der keine Parameter akzeptiert. Das ObjectDataSource-Steuerelement ruft diesen Konstruktor auf, wenn er eine neue Instanz des Quellobjekts erstellt.

Wenn das Quellobjekt keinen öffentlichen Konstruktor ohne Parameter enthält, können Sie eine Instanz des Quellobjekts erstellen, das vom ObjectDataSource-Steuerelement im ObjectCreating-Ereignis verwendet wird.

Spezifizieren von Objektmethoden

Das Quellobjekt für ein ObjectDataSource-Steuerelement kann eine beliebige Anzahl von Methoden enthalten, die zum Auswählen, Einfügen, Aktualisieren oder Löschen von Daten verwendet werden. Diese Methoden werden vom ObjectDataSource-Steuerelement basierend auf dem Namen der Methode aufgerufen, der durch die SelectMethod-, InsertMethod-, UpdateMethod- oder DeleteMethod-Eigenschaft desselben identifiziert wird. Das Quellobjekt kann auch eine optionale SelectCount-Methode enthalten, die vom ObjectDataSource-Steuerelement mithilfe der SelectCountMethod-Eigenschaft identifiziert wird, die die Anzahl der Objekte an der Datenquelle zurückgibt. Das ObjectDataSource-Steuerelement ruft die Methode SelectCount auf, nachdem die Methode Select aufgerufen wurde, um die Gesamtanzahl der Datensätze an der Datenquelle abzurufen, die für das Paging verwendet wird.

Laborübung mit Datenquellensteuerungen

Übung 1 – Anzeigen von Daten mit dem SqlDataSource-Steuerelement

In der folgenden Übung wird das SqlDataSource-Steuerelement verwendet, um eine Verbindung mit der Northwind-Datenbank herzustellen. Es wird davon ausgegangen, dass Sie Zugriff auf die Northwind-Datenbank in einer SQL Server 2000-Instanz haben.

  1. Erstellen Sie eine neue ASP.NET-Website.

  2. Fügen Sie eine neue web.config Datei hinzu.

    1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und klicken Sie auf "Neues Element hinzufügen".
    2. Wählen Sie in der Liste der Vorlagen die Webkonfigurationsdatei aus, und klicken Sie auf "Hinzufügen".
  3. Bearbeiten Sie den <Abschnitt connectionStrings> wie folgt:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products">
    </asp:SqlDataSource>
    
  4. Wechseln Sie zur Codeansicht, und fügen Sie dem asp:SqlDataSource-Steuerelement< wie folgt ein ConnectionString-Attribut und ein SelectCommand-Attribut hinzu>:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products">
    </asp:SqlDataSource>
    
  5. Fügen Sie in der Entwurfsansicht ein neues GridView-Steuerelement hinzu.

  6. Wählen Sie im Dropdownmenü "Datenquelle auswählen" im Menü "GridView-Aufgaben" die Option "SqlDataSource1" aus.

  7. Klicken Sie mit der rechten Maustaste auf Default.aspx, und wählen Sie im Menü "Im Browser anzeigen" aus. Klicken Sie auf "Ja", wenn Sie zum Speichern aufgefordert werden.

  8. GridView zeigt die Daten aus der Tabelle "Produkte" an.

Übung 2 – Bearbeiten von Daten mit dem SqlDataSource-Steuerelement

In der folgenden Übung wird veranschaulicht, wie Sie ein DropDownList-Steuerelement mithilfe der deklarativen Syntax binden und die im DropDownList-Steuerelement dargestellten Daten bearbeiten können.

  1. Löschen Sie in der Entwurfsansicht das GridView-Steuerelement aus Default.aspx.

    Wichtig: Lassen Sie das SqlDataSource-Steuerelement auf der Seite.

  2. Fügen Sie ein DropDownList-Steuerelement zum Default.aspx hinzu.

  3. Wechseln zur Quellansicht.

  4. Fügen Sie dem <asp:DropDownList-Steuerelement> ein DataSourceId-, DataTextField- und DataValueField-Attribut wie folgt hinzu:

    <asp:DropDownList ID="ddlProducts" runat="server"
         DataSourceId="SqlDataSource1" DataTextField="ProductName"
         DataValueField="ProductID">
    </asp:DropDownList>
    
  5. Speichern Sie Default.aspx, und zeigen Sie sie im Browser an. Beachten Sie, dass die DropDownList alle Produkte aus der Northwind-Datenbank enthält.

  6. Schließen Sie den Browser.

  7. Fügen Sie in der Quellansicht von Default.aspx ein neues TextBox-Steuerelement unterhalb des DropDownList-Steuerelements hinzu. Ändern Sie die ID-Eigenschaft des TextBox-Objekts in txtProductName.

  8. Fügen Sie unter dem TextBox-Steuerelement ein neues Schaltflächen-Steuerelement hinzu. Ändern Sie die ID-Eigenschaft der Schaltfläche in btnUpdate und die Text-Eigenschaft in "Produktname aktualisieren".

  9. Fügen Sie in der Quellansicht von Default.aspx eine UpdateCommand-Eigenschaft und zwei neue UpdateParameters wie folgt zum SqlDataSource-Tag hinzu:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products"
        UpdateCommand="UPDATE Products SET ProductName=@ProductName WHERE ProductID=@ProductID">
          <UpdateParameters>
          <asp:ControlParameter Name="ProductName" 
            ControlID="txtProductName" PropertyName="Text" />
          <asp:ControlParameter Name="ProductID" 
            ControlID="ddlProducts" PropertyName="SelectedValue" />
    </asp:SqlDataSource>
    

    Hinweis

    Beachten Sie, dass in diesem Code zwei Updateparameter (ProductName und ProductID) hinzugefügt werden. Diese Parameter werden der Text-Eigenschaft des txtProductName TextBox- und der SelectedValue-Eigenschaft der ddlProducts DropDownList zugeordnet.

  10. Wechseln Sie zur Entwurfsansicht, und doppelklicken Sie auf das Schaltflächensteuerelement, um einen Ereignishandler hinzuzufügen.

  11. Fügen Sie dem code btnUpdate_Click den folgenden Code hinzu:

    SqlDataSource1.Update();
    
  12. Klicken Sie mit der rechten Maustaste auf Default.aspx, und wählen Sie aus, ob sie im Browser angezeigt werden soll. Klicken Sie auf "Ja", wenn Sie aufgefordert werden, alle Änderungen zu speichern.

  13. ASP.NET 2.0 Teilklassen ermöglichen die Kompilierung zur Laufzeit. Es ist nicht erforderlich, eine Anwendung zu erstellen, damit Codeänderungen wirksam werden.

  14. Wählen Sie ein Produkt aus der DropDownList aus.

  15. Geben Sie im Textfeld einen neuen Namen für das ausgewählte Produkt ein, und klicken Sie dann auf die Schaltfläche "Aktualisieren".

  16. Der Produktname wird in der Datenbank aktualisiert.

Übung 3: Verwenden des ObjectDataSource-Steuerelements

In dieser Übung wird die Verwendung des ObjectDataSource-Steuerelements und eines Quellobjekts für die Interaktion mit der Northwind-Datenbank veranschaulicht.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und klicken Sie auf "Neues Element hinzufügen".

  2. Wählen Sie "Webformular" in der Vorlagenliste aus. Ändern Sie den Namen in object.aspx, und klicken Sie auf "Hinzufügen".

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und klicken Sie auf "Neues Element hinzufügen".

  4. Wählen Sie "Klasse" in der Vorlagenliste aus. Ändern Sie den Namen der Klasse in NorthwindData.cs, und klicken Sie auf "Hinzufügen".

  5. Klicken Sie auf "Ja", wenn Sie aufgefordert werden, die Klasse zum Ordner App_Code hinzuzufügen.

  6. Fügen Sie der datei NorthwindData.cs den folgenden Code hinzu:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Data.SqlClient;
    public class NorthwindData {
        private string _connectionString;
        public NorthwindData() {
            Initialize();
        }
    
        private void Initialize() {
            if (ConfigurationManager.ConnectionStrings["Northwind"] == null ||
                ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString.Trim() == "") {
                    throw new Exception("A connection string named 'Northwind' with " +
                    "a valid connection string must exist in the <connectionStrings> " +
                    "configuration section for the application.");
            }
            _connectionString = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
        }
    
        public DataTable GetAllEmployees(string sortColumns, int startRecord, int maxRecords) {
            VerifySortColumns(sortColumns);
            string sqlCmd = "SELECT EmployeeID, LastName, FirstName, Address, " +
                "City, Region, PostalCode FROM Employees ";
            if (sortColumns.Trim() == "")
                sqlCmd += "ORDER BY EmployeeID";
            else
                sqlCmd += "ORDER BY " + sortColumns;
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlDataAdapter da = new SqlDataAdapter(sqlCmd, conn);
            DataSet ds = new DataSet();
            try {
                conn.Open();
                da.Fill(ds, startRecord, maxRecords, "Employees");
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return ds.Tables["Employees"];
        }
    
        public int SelectCount() {
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Employees", conn);
            int result = 0;
    
            try {
                conn.Open();
                result = (int)cmd.ExecuteScalar();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return result;
        }
    
        //////////
        // Verify that only valid columns are specified in the sort expression to
        // avoid a SQL Injection attack.
        private void VerifySortColumns(string sortColumns) {
            if (sortColumns.ToLowerInvariant().EndsWith(" desc"))
                sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);
            string[] columnNames = sortColumns.Split(',');
            foreach (string columnName in columnNames) {
                switch (columnName.Trim().ToLowerInvariant()) {
                    case "employeeid":
                        break;
                    case "lastname":
                        break;
                    case "firstname":
                        break;
                    case "":
                        break;
                    default:
                        throw new ArgumentException("SortColumns contains an " +
                            "invalid column name.");
                        break;
                }
            }
        }
    
        // Select an employee.
        public DataTable GetEmployee(int EmployeeID) {
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlDataAdapter da =
                new SqlDataAdapter("SELECT EmployeeID, LastName, FirstName, " +
                "Address, City, Region, PostalCode " +
                " FROM Employees WHERE EmployeeID = @EmployeeID", conn);
            da.SelectCommand.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
            DataSet ds = new DataSet();
            try {
                conn.Open();
                da.Fill(ds, "Employees");
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return ds.Tables["Employees"];
        }
    
        // Delete the Employee by ID.
        public int DeleteEmployee(int EmployeeID) {
             SqlConnection conn = new SqlConnection(_connectionString);
             SqlCommand cmd = new SqlCommand("DELETE FROM Employees WHERE " +
                 "EmployeeID = @EmployeeID", conn);
             cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
             int result = 0;
             try {
                 conn.Open();
                 result = cmd.ExecuteNonQuery();
             } catch (SqlException e) {
                 // Handle exception.
             } finally {
                 conn.Close();
             }
    
             return result;
         }
    
         // Update the Employee by original ID.
         public int UpdateEmployee(int EmployeeID, string LastName, string FirstName,
             string Address, string City, string Region,
             string PostalCode) {
             if (String.IsNullOrEmpty(FirstName))
                 throw new ArgumentException("FirstName cannot be null or an empty string.");
             if (String.IsNullOrEmpty(LastName))
                 throw new ArgumentException("LastName cannot be null or an empty string.");
             if (Address == null) { Address = String.Empty; }
             if (City == null) { City = String.Empty; }
             if (Region == null) { Region = String.Empty; }
             if (PostalCode == null) { PostalCode = String.Empty; }
    
             SqlConnection conn = new SqlConnection(_connectionString);
             SqlCommand cmd = new SqlCommand("UPDATE Employees " +
                 " SET FirstName=@FirstName, " +
                 "LastName=@LastName, " +
                 "Address=@Address, City=@City, " +
                 "Region=@Region, " +
                 "PostalCode=@PostalCode " +
                 "WHERE EmployeeID=@EmployeeID", conn);
             cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
             cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
             cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
             cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
             cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
             cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
             cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
    
             int result = 0;
             try {
                 conn.Open();
                 result = cmd.ExecuteNonQuery();
             } catch (SqlException e) {
                 // Handle exception.
             } finally {
                 conn.Close();
             }
    
             return result;
        }
    
        // Insert an Employee.
        public int InsertEmployee(string LastName, string FirstName,
            string Address, string City, string Region,
            string PostalCode) {
            if (String.IsNullOrEmpty(FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (Address == null) { Address = String.Empty; }
            if (City == null) { City = String.Empty; }
            if (Region == null) { Region = String.Empty; }
            if (PostalCode == null) { PostalCode = String.Empty; }
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand("INSERT INTO Employees " +
                " (FirstName, LastName, Address, " +
                " City, Region, PostalCode) " +
                " Values(@FirstName, @LastName, " +
                "@Address, @City, @Region, @PostalCode); " +
                "SELECT @EmployeeID = SCOPE_IDENTITY()", conn);
    
            cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
            cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
            cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
            cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
            cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
            cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
            SqlParameter p = cmd.Parameters.Add("@EmployeeID", SqlDbType.Int);
                p.Direction = ParameterDirection.Output;
            int newEmployeeID = 0;
            try {
                conn.Open();
                cmd.ExecuteNonQuery();
                newEmployeeID = (int)p.Value;
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return newEmployeeID;
        }
    
        //
        // Methods that support Optimistic Concurrency checks.
        //
        // Delete the Employee by ID.
        public int DeleteEmployee(int original_EmployeeID, string original_LastName,
            string original_FirstName, string original_Address,
            string original_City, string original_Region,
            string original_PostalCode) {
    
            if (String.IsNullOrEmpty(original_FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(original_LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (original_Address == null) { original_Address = String.Empty; }
            if (original_City == null) { original_City = String.Empty; }
            if (original_Region == null) { original_Region = String.Empty; }
            if (original_PostalCode == null) { original_PostalCode = String.Empty; }
            string sqlCmd = "DELETE FROM Employees WHERE EmployeeID = " + @original_EmployeeID
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand(sqlCmd, conn);
            cmd.Parameters.Add("@original_EmployeeID",
                SqlDbType.Int).Value = original_EmployeeID;
            cmd.Parameters.Add("@original_FirstName",
                SqlDbType.VarChar, 10).Value = original_FirstName;
            cmd.Parameters.Add("@original_LastName",
                SqlDbType.VarChar, 20).Value = original_LastName;
            cmd.Parameters.Add("@original_Address",
                SqlDbType.VarChar, 60).Value = original_Address;
            cmd.Parameters.Add("@original_City",
                SqlDbType.VarChar, 15).Value = original_City;
            cmd.Parameters.Add("@original_Region",
                SqlDbType.VarChar, 15).Value = original_Region;
            cmd.Parameters.Add("@original_PostalCode",
                SqlDbType.VarChar, 10).Value = original_PostalCode;
    
            int result = 0;
            try {
                conn.Open();
                result = cmd.ExecuteNonQuery();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return result;
        }
    
        // Update the Employee by original ID.
        public int UpdateEmployee(string LastName, string FirstName,
            string Address, string City, string Region,
            string PostalCode, int original_EmployeeID,
            string original_LastName, string original_FirstName,
            string original_Address, string original_City,
            string original_Region, string original_PostalCode) {
    
            if (String.IsNullOrEmpty(FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (Address == null) { Address = String.Empty; }
            if (City == null) { City = String.Empty; }
            if (Region == null) { Region = String.Empty; }
            if (PostalCode == null) { PostalCode = String.Empty; }
            if (original_Address == null) { original_Address = String.Empty; }
            if (original_City == null) { original_City = String.Empty; }
            if (original_Region == null) { original_Region = String.Empty; }
            if (original_PostalCode == null) { original_PostalCode = String.Empty; }
    
            string sqlCmd = "UPDATE Employees " +
                " SET FirstName = @FirstName, LastName = @LastName, " +
                " Address = @Address, City = @City, Region = @Region, " +
                " PostalCode = @PostalCode " +
                " WHERE EmployeeID = @original_EmployeeID";
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand(sqlCmd, conn);
            cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
            cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
            cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
            cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
            cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
            cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
            cmd.Parameters.Add("@original_EmployeeID",
                SqlDbType.Int).Value = original_EmployeeID;
            cmd.Parameters.Add("@original_FirstName",
                SqlDbType.VarChar, 10).Value = original_FirstName;
            cmd.Parameters.Add("@original_LastName",
                SqlDbType.VarChar, 20).Value = original_LastName;
            cmd.Parameters.Add("@original_Address",
                SqlDbType.VarChar, 60).Value = original_Address;
            cmd.Parameters.Add("@original_City",
                SqlDbType.VarChar, 15).Value = original_City;
            cmd.Parameters.Add("@original_Region",
                SqlDbType.VarChar, 15).Value = original_Region;
            cmd.Parameters.Add("@original_PostalCode",
                SqlDbType.VarChar, 10).Value = original_PostalCode;
    
            int result = 0;
    
            try {
                conn.Open();
                result = cmd.ExecuteNonQuery();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return result;
        }
    }
    
  7. Fügen Sie der Quellansicht von object.aspx den folgenden Code hinzu:

    <%@ Page language="C#" %>
    <script RunAt="server">
    void EmployeesDetailsView_ItemInserted(Object sender, DetailsViewInsertedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    
    void EmployeesDetailsView_ItemUpdated(Object sender, DetailsViewUpdatedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    
    void EmployeesDetailsView_ItemDeleted(Object sender, DetailsViewDeletedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    void EmployeesGridView_OnSelectedIndexChanged(object sender, EventArgs e) {
        EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
            EmployeesGridView.SelectedDataKey.Value.ToString();
        EmployeesDetailsView.DataBind();
    }
    void EmployeeDetailsObjectDataSource_OnInserted(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
            e.ReturnValue.ToString();
        EmployeesDetailsView.DataBind();
    }
    void EmployeeDetailsObjectDataSource_OnUpdated(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        if ((int)e.ReturnValue == 0)
            Msg.Text = "Employee was not updated. Please try again.";
    }
    void EmployeeDetailsObjectDataSource_OnDeleted(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        if ((int)e.ReturnValue == 0)
            Msg.Text = "Employee was not deleted. Please try again.";
    }
    void Page_Load() {
        Msg.Text = "";
    }
    </script>
    <html>
      <body>
        <form id="Form1" runat="server">
          <h3>ObjectDataSource Example</h3>
          <asp:Label id="Msg" runat="server" ForeColor="Red" />
          <asp:ObjectDataSource
              ID="EmployeesObjectDataSource"
              runat="server"
              TypeName="NorthwindData"
              SortParameterName="SortColumns"
              EnablePaging="true"
              SelectCountMethod="SelectCount"
              StartRowIndexParameterName="StartRecord"
              MaximumRowsParameterName="MaxRecords"
              SelectMethod="GetAllEmployees" >
          </asp:ObjectDataSource>
          <asp:ObjectDataSource
              ID="EmployeeDetailsObjectDataSource"
              runat="server"
              TypeName="NorthwindData"
              ConflictDetection="CompareAllValues"
              OldValuesParameterFormatString="{0}"
              SelectMethod="GetEmployee"
              InsertMethod="InsertEmployee"
              UpdateMethod="UpdateEmployee"
              DeleteMethod="DeleteEmployee"
              OnInserted="EmployeeDetailsObjectDataSource_OnInserted"
              OnUpdated="EmployeeDetailsObjectDataSource_OnUpdated"
              OnDeleted="EmployeeDetailsObjectDataSource_OnDeleted">
              <SelectParameters>
                  <asp:Parameter Name="EmployeeID" Type="Int32" />
              </SelectParameters>
          </asp:ObjectDataSource>
          <table cellspacing="10">
            <tr>
              <td valign="top">
                <asp:GridView ID="EmployeesGridView"
                    DataSourceID="EmployeesObjectDataSource"
                    AutoGenerateColumns="false"
                    AllowSorting="true"
                    AllowPaging="true"
                    PageSize="5"
                    DataKeyNames="EmployeeID"
                    OnSelectedIndexChanged="EmployeesGridView_OnSelectedIndexChanged"
                    RunAt="server">
                    <HeaderStyle backcolor="lightblue" forecolor="black"/>
                    <Columns>
                    <asp:ButtonField Text="Details..."
                    HeaderText="Show Details"
                    CommandName="Select"/>
    
                    <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"
                    SortExpression="EmployeeID" />
                    <asp:BoundField DataField="FirstName" HeaderText="First Name"
                    SortExpression="FirstName" />
                    <asp:BoundField DataField="LastName" HeaderText="Last Name"
                    SortExpression="LastName, FirstName" />
                    </Columns>
                </asp:GridView>
              </td>
              <td valign="top">
                <asp:DetailsView ID="EmployeesDetailsView"
                    DataSourceID="EmployeeDetailsObjectDataSource"
                    AutoGenerateRows="false"
                    EmptyDataText="No records."
                    DataKeyNames="EmployeeID"
                    Gridlines="Both"
                    AutoGenerateInsertButton="true"
                    AutoGenerateEditButton="true"
                    AutoGenerateDeleteButton="true"
                    OnItemInserted="EmployeesDetailsView_ItemInserted"
                    OnItemUpdated="EmployeesDetailsView_ItemUpdated"
                    OnItemDeleted="EmployeesDetailsView_ItemDeleted"
                    RunAt="server">
                    <HeaderStyle backcolor="Navy" forecolor="White"/>
                    <RowStyle backcolor="White"/>
                    <AlternatingRowStyle backcolor="LightGray"/>
                    <EditRowStyle backcolor="LightCyan"/>
                    <Fields>
                        <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"
                            InsertVisible="False" ReadOnly="true"/>
                        <asp:BoundField DataField="FirstName" HeaderText="First Name"/>
                        <asp:BoundField DataField="LastName" HeaderText="Last Name"/>
                        <asp:BoundField DataField="Address" HeaderText="Address"/>
                        <asp:BoundField DataField="City" HeaderText="City"/>
                        <asp:BoundField DataField="Region" HeaderText="Region"/>
                        <asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>
                    </Fields>
                  </asp:DetailsView>
                </td>
              </tr>
            </table>
          </form>
        </body>
      </html>
    
  8. Speichern Sie alle Dateien, und durchsuchen Sie object.aspx.

  9. Interagieren Sie mit der Benutzeroberfläche, indem Sie Details anzeigen, Mitarbeiter bearbeiten, Mitarbeiter hinzufügen und Mitarbeiter löschen.