Wykonywanie aktualizacji wsadowych (VB)

Autor: Scott Mitchell

Pobierz plik PDF

Dowiedz się, jak utworzyć w pełni edytowalną listę danych, w której wszystkie jego elementy są w trybie edycji i których wartości można zapisać, klikając przycisk "Aktualizuj wszystko" na stronie.

Wprowadzenie

W poprzednim samouczku sprawdziliśmy, jak utworzyć listę danych na poziomie elementu. Podobnie jak w przypadku standardowego edytowalnego elementu GridView, każdy element na liście danych zawiera przycisk Edytuj, który po kliknięciu spowoduje, że element będzie edytowalny. Chociaż edytowanie na poziomie elementu działa dobrze w przypadku danych, które są aktualizowane tylko od czasu do czasu, niektóre scenariusze przypadków użycia wymagają od użytkownika edytowania wielu rekordów. Jeśli użytkownik musi edytować dziesiątki rekordów i musi kliknąć przycisk Edytuj, wprowadzić zmiany i kliknąć przycisk Aktualizuj dla każdego z nich, ilość kliknięć może utrudnić jej produktywność. W takich sytuacjach lepszym rozwiązaniem jest udostępnienie w pełni edytowalnej listy danych, w której wszystkie jego elementy są w trybie edycji i których wartości można edytować, klikając przycisk Aktualizuj wszystko na stronie (patrz Rysunek 1).

Każdy element w w pełni edytowalnej listy danych można modyfikować

Rysunek 1. Każdy element w w pełni edytowalnej listy danych można zmodyfikować (kliknij, aby wyświetlić obraz pełnowymiarowy)

W tym samouczku sprawdzimy, jak umożliwić użytkownikom aktualizowanie informacji o adresach dostawców przy użyciu w pełni edytowalnej listy danych.

Krok 1. Tworzenie edytowalnego interfejsu użytkownika w elemencie ItemTemplate elementu DataList

W poprzednim samouczku, w którym utworzyliśmy standardową, edytowalną listę danych na poziomie elementu, użyliśmy dwóch szablonów:

  • ItemTemplate zawierał interfejs użytkownika tylko do odczytu (kontrolki Etykieta sieci Web do wyświetlania nazwy i ceny poszczególnych produktów).
  • EditItemTemplate zawierał interfejs użytkownika trybu edycji (dwa kontrolki sieci Web TextBox).

Właściwość DataList EditItemIndex określa, co DataListItem (jeśli istnieje) jest renderowane przy użyciu elementu EditItemTemplate. W szczególności wartość, DataListItem której ItemIndex wartość jest zgodna z właściwością DataList, EditItemIndex jest renderowana przy użyciu elementu EditItemTemplate. Ten model działa dobrze, gdy tylko jeden element można edytować naraz, ale rozpada się podczas tworzenia w pełni edytowalnej listy danych.

W przypadku w pełni edytowalnej listy danych chcemy, aby wszystkieDataListItem elementy s renderowane przy użyciu interfejsu edytowalnego. Najprostszym sposobem na to jest zdefiniowanie edytowalnego interfejsu w pliku ItemTemplate. Aby zmodyfikować informacje o adresach dostawców, edytowalny interfejs zawiera nazwę dostawcy jako tekst, a następnie Pola tekstowe dla wartości adresu, miasta i kraju/regionu.

Zacznij od otwarcia BatchUpdate.aspx strony, dodaj kontrolkę DataList i ustaw jej ID właściwość na Suppliers. Z tagu inteligentnego DataList wybierz opcję dodania nowej kontrolki ObjectDataSource o nazwie SuppliersDataSource.

Tworzenie nowego obiektuDataSource o nazwie SuppliersDataSource

Rysunek 2. Utwórz nową nazwę ObjectDataSource o nazwie SuppliersDataSource (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Skonfiguruj obiekt ObjectDataSource, aby pobrać dane przy użyciu SuppliersBLL metody klasy s GetSuppliers() (zobacz Rysunek 3). Podobnie jak w przypadku poprzedniego samouczka, zamiast aktualizować informacje o dostawcy za pośrednictwem obiektu ObjectDataSource, będziemy pracować bezpośrednio z warstwą logiki biznesowej. W związku z tym ustaw listę rozwijaną na (Brak) na karcie UPDATE (zobacz Rysunek 4).

Pobieranie informacji o dostawcy przy użyciu metody GetSuppliers()

Rysunek 3. Pobieranie informacji o dostawcy przy użyciu GetSuppliers() metody (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ustaw listę Drop-Down na wartość (Brak) na karcie UPDATE

Rysunek 4. Ustawianie listy Drop-Down na wartość (Brak) na karcie UPDATE (Kliknij, aby wyświetlić obraz pełnowymiarowy)

Po ukończeniu pracy kreatora program Visual Studio automatycznie generuje listę ItemTemplate danych, aby wyświetlić każde pole danych zwrócone przez źródło danych w kontrolce Sieci Web etykiet. Musimy zmodyfikować ten szablon, aby zamiast tego udostępniał interfejs do edycji. Można ItemTemplate je dostosować za pomocą Projektant za pomocą opcji Edytuj szablony z tagu inteligentnego DataList lub bezpośrednio za pomocą składni deklaratywnej.

Poświęć chwilę na utworzenie interfejsu edycji, który wyświetla nazwę dostawcy jako tekst, ale zawiera pola TextBoxes dla wartości adresu dostawcy, miasta i kraju/regionu. Po wprowadzeniu tych zmian składnia deklaratywna strony powinna wyglądać podobnie do następującej:

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

Uwaga

Podobnie jak w przypadku poprzedniego samouczka, lista DataList w tym samouczku musi mieć włączony stan widoku.

W programie ItemTemplate używam dwóch nowych klas SupplierPropertyLabel CSS i SupplierPropertyValue, które zostały dodane do Styles.css klasy i skonfigurowane do używania tych samych ustawień stylu co ProductPropertyLabel klasy i ProductPropertyValue CSS.

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

Po wprowadzeniu tych zmian odwiedź tę stronę za pośrednictwem przeglądarki. Jak pokazano na rysunku 5, każdy element DataList wyświetla nazwę dostawcy jako tekst i używa pola TextBoxes do wyświetlania adresu, miasta i kraju/regionu.

Każdy dostawca na liście danych jest edytowalny

Rysunek 5. Każdy dostawca na liście danych jest edytowalny (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 2. Dodawanie przycisku Aktualizuj wszystko

Chociaż każdy dostawca na rysunku 5 ma swoje pola adresowe, miasto i kraj/region wyświetlane w polu TekstBox, obecnie nie ma dostępnego przycisku Aktualizuj. Zamiast przycisku Aktualizuj dla każdego elementu, w pełni edytowalne listy danych na stronie zazwyczaj znajduje się jeden przycisk Aktualizuj wszystko, który po kliknięciu aktualizuje wszystkie rekordy na liście Danych. W tym samouczku dodajmy dwa przyciski Aktualizuj wszystkie — jeden w górnej części strony i jeden u dołu (chociaż kliknięcie jednego przycisku będzie miało taki sam efekt).

Zacznij od dodania kontrolki Sieć Web przycisku nad listą DataList i ustaw jej ID właściwość na UpdateAll1. Następnie dodaj drugą kontrolkę Sieć Web przycisku pod listą DataList, ustawiając jej ID wartość na UpdateAll2. Text Ustaw właściwości dla dwóch przycisków na Wartość Aktualizuj wszystko. Na koniec utwórz programy obsługi zdarzeń dla obu zdarzeń Przycisków Click . Zamiast duplikować logikę aktualizacji w każdym z programów obsługi zdarzeń, refaktoryzujmy tę logikę do trzeciej metody , UpdateAllSupplierAddressesdzięki czemu programy obsługi zdarzeń po prostu wywołają tę trzecią metodę.

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

Rysunek 6 przedstawia stronę po dodaniu przycisków Aktualizuj wszystkie.

Do strony zostały dodane dwa przyciski Aktualizuj wszystkie

Rysunek 6. Dodano dwa przyciski Aktualizuj wszystkie do strony (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 3. Aktualizowanie wszystkich informacji o adresach dostawców

Po wyświetleniu interfejsu edycji i dodaniu wszystkich przycisków Aktualizuj wszystkie pozostałe elementy zapisuje kod do wykonania aktualizacji wsadowej. W szczególności musimy pętli przez elementy DataList i wywołać metodę SuppliersBLL klasy s UpdateSupplierAddress dla każdego z nich.

Do kolekcji DataListItem wystąpień, do których można uzyskać dostęp za pośrednictwem właściwości DataListItems. Przy odwołaniu do elementu DataListItemmożemy pobrać odpowiedni SupplierID element z DataKeys kolekcji i programowo odwołać się do kontrolek sieci Web TextBox w ItemTemplate programie , jak pokazano w poniższym kodzie:

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

Gdy użytkownik kliknie jeden z przycisków Aktualizuj wszystkie, UpdateAllSupplierAddresses metoda wykonuje iterację po każdej DataListItem z nich w elemecie Suppliers DataList i wywołuje SuppliersBLL metodę klasy s UpdateSupplierAddress , przekazując odpowiednie wartości. Niewprowadzona wartość dla adresu, miasta lub kraju/regionu jest wartością Nothing do UpdateSupplierAddress (zamiast pustego ciągu), co powoduje utworzenie bazy danych NULL dla pól rekordu bazowego.

Uwaga

W ramach ulepszenia możesz dodać kontrolkę sieci Web etykieta stanu do strony, która dostarcza komunikat potwierdzający po wykonaniu aktualizacji wsadowej.

Aktualizowanie tylko tych adresów, które zostały zmodyfikowane

Algorytm aktualizacji wsadowej używany w tym samouczku wywołuje metodę UpdateSupplierAddress dla każdego dostawcy w liście DataList, niezależnie od tego, czy informacje o adresach zostały zmienione. Chociaż takie niewidome aktualizacje nie są zwykle problemem z wydajnością, mogą prowadzić do nadmiarowych rekordów, jeśli przeprowadzasz inspekcję zmian w tabeli bazy danych. Jeśli na przykład używasz wyzwalaczy do rejestrowania wszystkich UPDATE elementów w Suppliers tabeli do tabeli inspekcji, za każdym razem, gdy użytkownik kliknie przycisk Aktualizuj wszystko, zostanie utworzony nowy rekord inspekcji dla każdego dostawcy w systemie, niezależnie od tego, czy użytkownik dokonał jakichkolwiek zmian.

Klasy ADO.NET DataTable i DataAdapter są przeznaczone do obsługi aktualizacji wsadowych, w których tylko zmodyfikowane, usunięte i nowe rekordy będą skutkować komunikacją z dowolną bazą danych. Każdy wiersz w tabeli DataTable ma właściwość wskazującąRowState, czy wiersz został dodany do tabeli DataTable, usunięty z niego, zmodyfikowany lub pozostaje niezmieniony. Gdy tabela danych jest początkowo wypełniana, wszystkie wiersze są oznaczone bez zmian. Zmiana wartości dowolnej kolumny wiersza oznacza wiersz zgodnie z modyfikacją.

SuppliersBLL W klasie aktualizujemy informacje o adresach określonego dostawcy, najpierw odczytując w rekordzie pojedynczego dostawcySuppliersDataTable, a następnie ustawiamy Addresswartości kolumn , Cityi Country przy użyciu następującego kodu:

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

Ten kod naiwnie przypisuje przekazane wartości adresu, miasta i kraju/regionu do SuppliersRow wartości w SuppliersDataTable niezależnie od tego, czy wartości uległy zmianie. Te modyfikacje powodują SuppliersRow oznaczenie właściwości s RowState jako zmodyfikowanej. Gdy wywoływana jest metoda warstwy Update dostępu do danych, zobaczy, że SupplierRow element został zmodyfikowany i dlatego wysyła UPDATE polecenie do bazy danych.

Załóżmy jednak, że dodaliśmy kod do tej metody w celu przypisania tylko przekazanych wartości adresu, miasta i kraju/regionu, jeśli różnią się od SuppliersRow istniejących wartości. W przypadku, gdy adres, miasto i kraj/region są takie same jak istniejące dane, nie zostaną wprowadzone żadne zmiany, a SupplierRow znaki s RowState zostaną oznaczone jako niezmienione. Wynikiem netto jest to, że po wywołaniu metody DAL Update nie zostanie wykonane żadne wywołanie bazy danych, ponieważ SuppliersRow nie został zmodyfikowany.

Aby wprowadzić tę zmianę, zastąp instrukcje, które ślepo przypisują przekazany adres, miasto i wartości kraju/regionu następującym kodem:

' 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

Dzięki temu dodanemu kodzie metoda DAL Update wysyła instrukcję UPDATE do bazy danych tylko dla tych rekordów, których wartości związane z adresami uległy zmianie.

Alternatywnie można śledzić, czy istnieją jakiekolwiek różnice między przekazanymi polami adresów a danymi bazy danych, a jeśli nie ma ich, po prostu pominąć wywołanie metody DAL Update . Takie podejście działa dobrze, jeśli używasz metody bezpośredniej bazy danych, ponieważ metoda bezpośrednia bazy danych nie jest przekazywana SuppliersRow do wystąpienia, którego RowState można sprawdzić, czy wywołanie bazy danych jest rzeczywiście potrzebne.

Uwaga

Za każdym razem, gdy UpdateSupplierAddress metoda jest wywoływana, do bazy danych jest wykonywane wywołanie w celu pobrania informacji o zaktualizowanym rekordzie. Następnie, jeśli istnieją jakiekolwiek zmiany w danych, następuje kolejne wywołanie bazy danych w celu zaktualizowania wiersza tabeli. Ten przepływ pracy można zoptymalizować, tworząc UpdateSupplierAddress przeciążenie metody, które akceptuje EmployeesDataTable wystąpienie, które zawiera wszystkie zmiany ze BatchUpdate.aspx strony. Następnie może wykonać jedno wywołanie bazy danych, aby pobrać wszystkie rekordy z Suppliers tabeli. Te dwa zestawy wyników można następnie wyliczyć i tylko te rekordy, w których wystąpiły zmiany.

Podsumowanie

W tym samouczku pokazano, jak utworzyć w pełni edytowalną listę danych, umożliwiając użytkownikowi szybkie modyfikowanie informacji o adresie dla wielu dostawców. Zaczęliśmy od zdefiniowania interfejsu edycji kontrolki internetowej TextBox dla adresu dostawcy, miasta i kraju/regionu wartości w elemecie DataList s ItemTemplate. Następnie dodaliśmy przyciski Aktualizuj wszystkie powyżej i poniżej listy danych. Po wprowadzeniu zmian przez użytkownika i kliknięciu jednego z przycisków Aktualizuj wszystkie zostaną wyliczone DataListItem , a wywołanie SuppliersBLL metody klasy s UpdateSupplierAddress zostanie wykonane.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Zack Jones i Ken Pespisa. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .