Freigeben über


Durchführen von Batchupdates (VB)

von Scott Mitchell

PDF herunterladen

Erfahren Sie, wie Sie eine vollständig bearbeitbare DataList erstellen, in der sich alle zugehörigen Elemente im Bearbeitungsmodus befinden und deren Werte gespeichert werden können, indem Sie auf der Seite auf eine Schaltfläche "Alle aktualisieren" klicken.

Einführung

Im vorherigen Lernprogramm haben wir untersucht, wie eine DataList auf Elementebene erstellt wird. Wie bei der standardmäßigen bearbeitbaren GridView enthielt jedes Element in der DataList eine Bearbeitungsschaltfläche, die beim Klicken auf das Element bearbeitbar wäre. Die Bearbeitung auf Elementebene eignet sich zwar gut für Daten, die nur gelegentlich aktualisiert werden, aber bestimmte Anwendungsfallszenarien erfordern, dass der Benutzer viele Datensätze bearbeiten kann. Wenn ein Benutzer Dutzende von Datensätzen bearbeiten muss und gezwungen ist, auf "Bearbeiten" zu klicken, seine Änderungen vorzunehmen und auf "Aktualisieren" zu klicken, kann die Anzahl des Klickens ihre Produktivität beeinträchtigen. In solchen Situationen besteht eine bessere Option darin, eine vollständig bearbeitbare DataList bereitzustellen, bei der sich alle zugehörigen Elemente im Bearbeitungsmodus befinden und deren Werte durch Klicken auf eine Schaltfläche "Alle aktualisieren" auf der Seite bearbeitet werden können (siehe Abbildung 1).

Jedes Element in einer vollständig bearbeitbaren DataList kann geändert werden.

Abbildung 1: Jedes Element in einer vollständig bearbeitbaren DataList kann geändert werden (Klicken, um das Bild in voller Größe anzuzeigen)

In diesem Lernprogramm untersuchen wir, wie Sie Benutzern das Aktualisieren von Lieferantenadresseninformationen mithilfe einer vollständig bearbeitbaren DataList ermöglichen.

Schritt 1: Erstellen der bearbeitbaren Benutzeroberfläche in der DataList s ItemTemplate

Im vorherigen Lernprogramm, in dem wir eine standardmäßige, bearbeitbare DataList auf Elementebene erstellen, haben wir zwei Vorlagen verwendet:

  • ItemTemplate enthält die schreibgeschützte Benutzeroberfläche (die Bezeichnungswebsteuerelemente zum Anzeigen des Jeweiligen Produktnamens und Preises).
  • EditItemTemplate enthält die Benutzeroberfläche des Bearbeitungsmodus (die beiden TextBox-Websteuerelemente).

Die DataList-Eigenschaft EditItemIndex bestimmt, was DataListItem (falls vorhanden) mithilfe der EditItemTemplate. Insbesondere wird der DataListItem Wert, dessen ItemIndex Wert mit der DataList-Eigenschaft EditItemIndex übereinstimmt, mithilfe der EditItemTemplate. Dieses Modell funktioniert gut, wenn jeweils nur ein Element bearbeitet werden kann, aber beim Erstellen einer vollständig bearbeitbaren DataList auseinanderfällt.

Für eine vollständig bearbeitbare DataList möchten wir, dass alle DataListItem Elemente mithilfe der bearbeitbaren Schnittstelle gerendert werden. Die einfachste Möglichkeit, dies zu erreichen, ist das Definieren der bearbeitbaren Schnittstelle in der ItemTemplate. Zum Ändern der Adressinformationen der Lieferanten enthält die bearbeitbare Schnittstelle den Lieferantennamen als Text und dann TextBoxes für die Werte "Adresse", "Ort" und "Land/Region".

Öffnen Sie zunächst die BatchUpdate.aspx Seite, fügen Sie ein DataList-Steuerelement hinzu, und legen Sie dessen ID Eigenschaft auf Suppliers. Wählen Sie aus dem Smarttag "DataList" ein neues ObjectDataSource-Steuerelement mit dem Namen .SuppliersDataSource

Erstellen einer neuen ObjectDataSource namens SuppliersDataSource

Abbildung 2: Erstellen einer neuen ObjectDataSource namens SuppliersDataSource (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Konfigurieren Sie objectDataSource so, dass Daten mithilfe der SuppliersBLL Klassenmethode GetSuppliers() abgerufen werden (siehe Abbildung 3). Wie im vorherigen Lernprogramm arbeiten wir, anstatt die Lieferanteninformationen über ObjectDataSource zu aktualisieren, direkt mit der Geschäftslogikebene zusammen. Legen Sie daher die Dropdownliste auf (Keine) auf der Registerkarte UPDATE fest (siehe Abbildung 4).

Abrufen von Lieferanteninformationen mithilfe der GetSuppliers() -Methode

Abbildung 3: Abrufen von Lieferanteninformationen mithilfe der GetSuppliers() Methode (Klicken, um das Bild in voller Größe anzuzeigen)

Festlegen der Dropdownliste auf (Keine) auf der Registerkarte

Abbildung 4: Festlegen der Dropdownliste auf (Keine) auf der Registerkarte "AKTUALISIEREN" (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nach Abschluss des Assistenten generiert Visual Studio automatisch die DataList-Elemente ItemTemplate , um jedes Datenfeld anzuzeigen, das von der Datenquelle in einem Bezeichnungswebsteuerelement zurückgegeben wird. Wir müssen diese Vorlage so ändern, dass sie stattdessen die Bearbeitungsschnittstelle bereitstellt. Dies ItemTemplate kann über den Designer mithilfe der Option "Vorlagen bearbeiten" aus dem Smarttag von DataList oder direkt über die deklarative Syntax angepasst werden.

Nehmen Sie sich einen Moment Zeit, um eine Bearbeitungsschnittstelle zu erstellen, die den Namen des Lieferanten als Text anzeigt, aber TextBoxes für die Adress-, Orts- und Länder-/Regionswerte des Lieferanten enthält. Nachdem Sie diese Änderungen vorgenommen haben, sollte die deklarative Syntax Ihrer Seite wie folgt aussehen:

<asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID"
    DataSourceID="SuppliersDataSource">
    <ItemTemplate>
        <h4><asp:Label ID="CompanyNameLabel" runat="server"
            Text='<%# Eval("CompanyName") %>' /></h4>
        <table border="0">
            <tr>
                <td class="SupplierPropertyLabel">Address:</td>
                <td class="SupplierPropertyValue">
                    <asp:TextBox ID="Address" runat="server"
                        Text='<%# Eval("Address") %>' />
                </td>
            </tr>
            <tr>
                <td class="SupplierPropertyLabel">City:</td>
                <td class="SupplierPropertyValue">
                    <asp:TextBox ID="City" runat="server"
                        Text='<%# Eval("City") %>' />
                </td>
            </tr>
            <tr>
                <td class="SupplierPropertyLabel">Country:</td>
                <td class="SupplierPropertyValue">
                    <asp:TextBox ID="Country" runat="server"
                        Text='<%# Eval("Country") %>' />
                </td>
            </tr>
        </table>
        <br />
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

Hinweis

Wie im vorherigen Lernprogramm muss die DataList in diesem Lernprogramm den Ansichtsstatus aktiviert haben.

In der ItemTemplate I m using two new CSS classes, SupplierPropertyLabel and SupplierPropertyValue, which been added to the Styles.css class and configured to use the same style settings as the ProductPropertyLabel and ProductPropertyValue CSS classes.

.ProductPropertyLabel, .SupplierPropertyLabel
{
    font-weight: bold;
    text-align: right;
}
.ProductPropertyValue, .SupplierPropertyValue
{
    padding-right: 35px;
}

Nachdem Sie diese Änderungen vorgenommen haben, besuchen Sie diese Seite über einen Browser. Wie in Abbildung 5 dargestellt, zeigt jedes DataList-Element den Lieferantennamen als Text an und verwendet TextBoxes zum Anzeigen der Adresse, des Orts und der Region.

Jeder Lieferant in der DataList kann bearbeitet werden.

Abbildung 5: Jeder Lieferant in der DataList ist bearbeitbar (Zum Anzeigen des Bilds mit voller Größe klicken)

Schritt 2: Hinzufügen einer Schaltfläche "Alle aktualisieren"

Während jeder Lieferant in Abbildung 5 die Felder "Adresse", "Ort" und "Land/Region" in einem TextBox-Element anzeigt, ist derzeit keine Schaltfläche "Aktualisieren" verfügbar. Anstatt eine Schaltfläche "Aktualisieren" pro Element zu haben, gibt es in der Regel eine einzelne Schaltfläche "Alle aktualisieren" auf der Seite, die alle Datensätze in der DataList aktualisiert. In diesem Lernprogramm fügen wir zwei Schaltflächen "Alle aktualisieren" hinzu – eine am oberen Rand der Seite und eine am unteren Rand (obwohl das Klicken auf eine der Schaltflächen denselben Effekt hat).

Fügen Sie zunächst ein Schaltflächenweb-Steuerelement oberhalb der DataList hinzu, und legen Sie dessen ID Eigenschaft auf UpdateAll1. Fügen Sie als Nächstes das zweite Schaltflächen-Websteuerelement unter der DataList hinzu, und legen Sie sie ID auf UpdateAll2. Legen Sie die Text Eigenschaften für die beiden Schaltflächen auf "Alle aktualisieren" fest. Erstellen Sie schließlich Ereignishandler für beide Schaltflächenereignisse Click . Anstatt die Aktualisierungslogik in jedem der Ereignishandler zu duplizieren, lassen Sie uns diese Logik in eine dritte Methode umgestalten, UpdateAllSupplierAddresseswobei die Ereignishandler einfach diese dritte Methode aufrufen.

Protected Sub UpdateAll1_Click(sender As Object, e As EventArgs) _
    Handles UpdateAll1.Click
    UpdateAllSupplierAddresses()
End Sub
Protected Sub UpdateAll2_Click(sender As Object, e As EventArgs) _
    Handles UpdateAll2.Click
    UpdateAllSupplierAddresses()
End Sub
Private Sub UpdateAllSupplierAddresses()
    ' TODO: Write code to update _all_ of the supplier addresses in the DataList
End Sub

Abbildung 6 zeigt die Seite, nachdem die Schaltflächen "Alle aktualisieren" hinzugefügt wurden.

Zwei Schaltflächen zum Aktualisieren aller Schaltflächen wurden der Seite hinzugefügt.

Abbildung 6: Zwei Schaltflächen aktualisieren wurden zur Seite hinzugefügt (Klicken, um das Bild in voller Größe anzuzeigen)

Schritt 3: Aktualisieren aller Adressinformationen der Lieferanten

Bei allen DataList-Elementen, die die Bearbeitungsoberfläche anzeigen, und mit dem Hinzufügen der Schaltflächen "Alle aktualisieren", schreibt alles, was weiterhin den Code schreibt, um die Batchaktualisierung durchzuführen. Insbesondere müssen wir die DataList-Elemente durchlaufen und die Methode der SuppliersBLL UpdateSupplierAddress Klasse für jede aufrufen.

Auf die Sammlung von DataListItem Instanzen, die die DataList erstellen, kann über die DataList-EigenschaftItems zugegriffen werden. Mit einem Verweis auf ein DataListItemObjekt können wir das entsprechende SupplierID aus der DataKeys Auflistung abrufen und programmgesteuert auf die TextBox-Websteuerelemente innerhalb des ItemTemplate folgenden Codes verweisen:

Private Sub UpdateAllSupplierAddresses()
    ' Create an instance of the SuppliersBLL class
    Dim suppliersAPI As New SuppliersBLL()
    ' Iterate through the DataList's items
    For Each item As DataListItem In Suppliers.Items
        ' Get the supplierID from the DataKeys collection
        Dim supplierID As Integer = Convert.ToInt32(Suppliers.DataKeys(item.ItemIndex))
        ' Read in the user-entered values
        Dim address As TextBox = CType(item.FindControl("Address"), TextBox)
        Dim city As TextBox = CType(item.FindControl("City"), TextBox)
        Dim country As TextBox = CType(item.FindControl("Country"), TextBox)
        Dim addressValue As String = Nothing, _
            cityValue As String = Nothing, _
            countryValue As String = Nothing
        If address.Text.Trim().Length > 0 Then
            addressValue = address.Text.Trim()
        End If
        If city.Text.Trim().Length > 0 Then
            cityValue = city.Text.Trim()
        End If
        If country.Text.Trim().Length > 0 Then
            countryValue = country.Text.Trim()
        End If
        ' Call the SuppliersBLL class's UpdateSupplierAddress method
        suppliersAPI.UpdateSupplierAddress _
            (supplierID, addressValue, cityValue, countryValue)
    Next
End Sub

Wenn der Benutzer auf eine der Schaltflächen "Alle aktualisieren" klickt, durchläuft die UpdateAllSupplierAddresses Methode jede DataListItem in der Suppliers DataList und ruft die Methode der SuppliersBLL Klasse UpdateSupplierAddress auf, wobei die entsprechenden Werte übergeben werden. Ein nicht eingegebener Wert für Adress-, Orts- oder Länder-/Regionsdurchläufe ist ein Wert von Nothing ( UpdateSupplierAddress anstelle einer leeren Zeichenfolge), der zu einer Datenbank NULL für die zugrunde liegenden Datensatzfelder führt.

Hinweis

Als Erweiterung möchten Sie der Seite möglicherweise ein Statusbezeichnung-Websteuerelement hinzufügen, das nach der Batchaktualisierung eine Bestätigungsmeldung bereitstellt.

Aktualisieren nur der Adressen, die geändert wurden

Der für dieses Lernprogramm verwendete Batchaktualisierungsalgorithmus ruft die UpdateSupplierAddress Methode für jeden Lieferanten in der DataList auf, unabhängig davon, ob ihre Adressinformationen geändert wurden. Während solche Blindupdates in der Regel kein Leistungsproblem sind, können sie zu überflüssigen Datensätzen führen, wenn Sie Änderungen an der Datenbanktabelle überwachen. Wenn Sie beispielsweise Trigger verwenden, um alle UPDATE S in der Suppliers Tabelle in einer Überwachungstabelle aufzuzeichnen, wird jedes Mal, wenn ein Benutzer auf die Schaltfläche "Alle aktualisieren" klickt, für jeden Lieferanten im System ein neuer Überwachungsdatensatz erstellt, unabhängig davon, ob der Benutzer Änderungen vorgenommen hat.

Die ADO.NET DataTable- und DataAdapter-Klassen sind so konzipiert, dass Batchaktualisierungen unterstützt werden, bei denen nur geänderte, gelöschte und neue Datensätze zu einer beliebigen Datenbankkommunikation führen. Jede Zeile in der DataTable weist eine RowState Eigenschaft auf, die angibt, ob die Zeile der DataTable hinzugefügt, daraus gelöscht, geändert oder unverändert bleibt. Wenn eine DataTable anfangs aufgefüllt wird, werden alle Zeilen unverändert markiert. Wenn Sie den Wert einer der Zeilenspalten ändern, wird die Zeile als geändert markiert.

In der SuppliersBLL Klasse aktualisieren wir die angegebenen Adressinformationen des Lieferanten durch erstes Lesen im Datensatz des einzelnen Lieferanten in einen SuppliersDataTable und legen dann die AddressWerte Cityund Country Spaltenwerte mithilfe des folgenden Codes fest:

Public Function UpdateSupplierAddress _
    (supplierID As Integer, address As String, city As String, country As String) _
    As Boolean
    Dim suppliers As Northwind.SuppliersDataTable = _
        Adapter.GetSupplierBySupplierID(supplierID)
    If suppliers.Count = 0 Then
        ' no matching record found, return false
        Return False
    Else
        Dim supplier As Northwind.SuppliersRow = suppliers(0)
        If address Is Nothing Then
            supplier.SetAddressNull()
        Else
            supplier.Address = address
        End If
        If city Is Nothing Then
            supplier.SetCityNull()
        Else
            supplier.City = city
        End If
        If country Is Nothing Then
            supplier.SetCountryNull()
        Else
            supplier.Country = country
        End If
        ' Update the supplier Address-related information
        Dim rowsAffected As Integer = Adapter.Update(supplier)
        ' Return true if precisely one row was updated, otherwise false
        Return rowsAffected = 1
    End If
End Function

Dieser Code weist den übergebenen Adress-, Orts- und Länder-/Regionswerten naiv die Werte unabhängig SuppliersDataTable davon zuSuppliersRow, ob sich die Werte geändert haben. Diese Änderungen bewirken, dass die SuppliersRow Eigenschaft s RowState als geändert markiert wird. Wenn die Data Access Layer-Methode Update aufgerufen wird, sieht sie, dass die SupplierRow Änderung erfolgt ist und sendet daher einen UPDATE Befehl an die Datenbank.

Stellen Sie sich jedoch vor, dass wir dieser Methode Code hinzugefügt haben, um nur die übergebenen Adress-, Orts- und Länder-/Regionswerte zuzuweisen, wenn sie sich von den SuppliersRow vorhandenen Werten unterscheiden. Wenn die Adresse, die Stadt und die Region mit den vorhandenen Daten identisch sind, werden keine Änderungen vorgenommen, und die SupplierRow Daten RowState werden unverändert markiert. Das Nettoergebnis ist, dass beim Aufrufen der DAL-Methode Update kein Datenbankaufruf erfolgt, da die SuppliersRow Methode nicht geändert wurde.

Um diese Änderung zu erlassen, ersetzen Sie die Anweisungen, die blind die übergebenen Adress-, Orts- und Länder-/Regionswerte durch den folgenden Code zuweisen:

' Only assign the values to the SupplierRow's column values if they differ
If address Is Nothing AndAlso Not supplier.IsAddressNull() Then
    supplier.SetAddressNull()
ElseIf (address IsNot Nothing AndAlso supplier.IsAddressNull) _
    OrElse (Not supplier.IsAddressNull() AndAlso _
                String.Compare(supplier.Address, address) <> 0) Then
    supplier.Address = address
End If
If city Is Nothing AndAlso Not supplier.IsCityNull() Then
    supplier.SetCityNull()
ElseIf (city IsNot Nothing AndAlso supplier.IsCityNull) _
    OrElse (Not supplier.IsCityNull() AndAlso _
                String.Compare(supplier.City, city) <> 0) Then
    supplier.City = city
End If
If country Is Nothing AndAlso Not supplier.IsCountryNull() Then
    supplier.SetCountryNull()
ElseIf (country IsNot Nothing AndAlso supplier.IsCountryNull) _
    OrElse (Not supplier.IsCountryNull() AndAlso _
                String.Compare(supplier.Country, country) <> 0) Then
    supplier.Country = country
End If

Mit diesem hinzugefügten Code sendet die DAL-Methode Update eine UPDATE Anweisung nur für die Datensätze, deren adressbezogene Werte geändert wurden.

Alternativ können wir nachverfolgen, ob es Unterschiede zwischen den übergebenen Adressfeldern und den Datenbankdaten gibt. Wenn keines vorhanden ist, umgehen Sie einfach den Aufruf der DAL s-Methode Update . Dieser Ansatz funktioniert gut, wenn Sie die direkte DB-Methode verwenden, da die DIREKTE DB-Methode keine Instanz übergeben SuppliersRow wird, deren RowState Überprüfung durchgeführt werden kann, um festzustellen, ob ein Datenbankaufruf tatsächlich benötigt wird.

Hinweis

Jedes Mal, wenn die UpdateSupplierAddress Methode aufgerufen wird, wird ein Aufruf der Datenbank ausgeführt, um Informationen zum aktualisierten Datensatz abzurufen. Wenn dann Änderungen an den Daten vorliegen, wird ein weiterer Aufruf der Datenbank vorgenommen, um die Tabellenzeile zu aktualisieren. Dieser Workflow kann optimiert werden, indem eine UpdateSupplierAddress Methodenüberladung erstellt wird, die eine EmployeesDataTable Instanz akzeptiert, die alle Änderungen von der BatchUpdate.aspx Seite enthält. Anschließend könnte die Datenbank einen Aufruf ausführen, um alle Datensätze aus der Suppliers Tabelle abzurufen. Die beiden Resultsets können dann aufgezählt werden, und nur die Datensätze, in denen Änderungen vorgenommen wurden, konnten aktualisiert werden.

Zusammenfassung

In diesem Lernprogramm haben wir erfahren, wie Sie eine vollständig bearbeitbare DataList erstellen, sodass ein Benutzer die Adressinformationen für mehrere Lieferanten schnell ändern kann. Wir haben begonnen, die Bearbeitungsschnittstelle ein TextBox-Websteuerelement für die Adressen, Ort und Länder/Region des Lieferanten in den DataList s ItemTemplatezu definieren. Als Nächstes haben wir oben und unterhalb der DataList "Alle aktualisieren"-Schaltflächen hinzugefügt. Nachdem ein Benutzer seine Änderungen vorgenommen und auf eine der Schaltflächen "Alle aktualisieren" geklickt hat, werden die DataListItem Elemente aufgezählt, und ein Aufruf der Methode der SuppliersBLL Klasse UpdateSupplierAddress erfolgt.

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 über mitchell@4GuysFromRolla.com seinen Blog erreicht werden, der unter .http://ScottOnWriting.NET

Besonderer Dank an

Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Zack Jones und Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn dies der Fall ist, legen Sie mir eine Zeile bei mitchell@4GuysFromRolla.com.