Udostępnij za pośrednictwem


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ć element DataList na poziomie elementu. Podobnie jak w przypadku standardowego edytowalnego widoku GridView, każdy element w elemencie DataList zawierał przycisk Edytuj, który po kliknięciu sprawi, ż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 DataList, 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 (zobacz 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 DataList.

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 służące 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 .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 DataList chcemy , aby wszystkie DataListItem s renderowane przy użyciu interfejsu edytowalnego. Najprostszym sposobem osiągnięcia tego celu 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 strony, dodania kontrolki BatchUpdate.aspx DataList i ustawienia jej ID właściwości na Suppliers. Z tagu inteligentnego DataList wybierz opcję dodania nowej kontrolki ObjectDataSource o nazwie SuppliersDataSource.

Tworzenie nowego obiektuDataSource o nazwie SuppliersDataSource

Rysunek 2. Tworzenie nowego obiektuDataSource 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 wartość (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ę rozwijaną na (Brak) na karcie UPDATE

Rysunek 4. Ustaw listę rozwijaną na (Brak) na karcie AKTUALIZACJA (kliknij, aby wyświetlić obraz pełnowymiarowy)

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

Pośmiń 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 narzędziu 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 w liście DataList jest edytowalny (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

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 tekstowym, obecnie nie ma dostępnego przycisku Aktualizuj. Zamiast mieć przycisk Aktualizuj dla każdego elementu, z w pełni edytowalnymi elementami DataLists na stronie jest zwykle jeden przycisk Aktualizuj wszystko, który po kliknięciu aktualizuje wszystkie rekordy w liście DataList. W tym samouczku dodajmy dwa przyciski Aktualizuj wszystkie — jeden w górnej części strony i jeden na dole (chociaż kliknięcie jednego przycisku będzie miało taki sam efekt).

Zacznij od dodania kontrolki Sieć Web przycisku powyżej kontrolki DataList i ustaw jej ID właściwość na UpdateAll1. Następnie dodaj drugą kontrolkę Sieć Web przycisku poniżej kontrolki DataList, ustawiając jej ID wartość na UpdateAll2. Text Ustaw właściwości dla dwóch przycisków na 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 procedury 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.

Dodano dwa przyciski Aktualizuj wszystkie do strony

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

W przypadku wszystkich elementów elementu DataList wyświetlających interfejs edycji i dodawania przycisków Aktualizuj wszystkie pozostaje napisanie kodu w celu przeprowadzenia aktualizacji wsadowej. W szczególności musimy przeprowadzić pętlę przez elementy elementu DataList i wywołać metodę SuppliersBLL s UpdateSupplierAddress klasy dla każdego z nich.

Kolekcja DataListItem wystąpień, do których można uzyskać dostęp za pośrednictwem właściwości DataListItems. Przy użyciu odwołania 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 metodzie Suppliers DataList i wywołuje SuppliersBLL metodę s UpdateSupplierAddress klasy, przekazując odpowiednie wartości. Niewprowadzona wartość dla adresu, miasta lub kraju/regionu jest wartością Nothing do UpdateSupplierAddress (zamiast pustego ciągu), która powoduje, że baza danych NULL dla pól rekordu bazowego.

Uwaga

W ramach ulepszenia możesz dodać kontrolkę Etykieta stanu w sieci Web do strony zawierającej 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 usłudze DataList, niezależnie od tego, czy informacje o adresach zostały zmienione. Chociaż takie ślepe 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 s Suppliers w 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 prowadzą do komunikacji 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 niej, zmodyfikowany lub pozostaje niezmieniony. Po początkowym wypełnieniu tabeli DataTable wszystkie wiersze są oznaczone bez zmian. Zmiana wartości dowolnej kolumny wierszy oznacza wiersz zgodnie z modyfikacją.

SuppliersBLL W klasie aktualizujemy informacje o adresach określonego dostawcy, najpierw odczytując w rekordzie pojedynczego dostawcy do SuppliersDataTable elementu , 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 elementu w SuppliersDataTable niezależnie od tego, czy wartości zostały zmienione. Te modyfikacje powodują SuppliersRow oznaczenie właściwości s RowState jako zmodyfikowanej. Po wywołaniu metody warstwy Update dostępu do danych zobaczysz, że SupplierRow element został zmodyfikowany i w związku z UPDATE tym wysyła 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ę one 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 net 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

W przypadku tego dodanego kodu 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ą jakieś różnice między przekazanymi polami adresów a danymi bazy danych, a jeśli ich nie ma, po prostu pomiń wywołanie metody DAL Update . Takie podejście sprawdza się 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, zostanie wykonane 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. Następnie można wyliczyć dwa zestawy wyników i tylko te rekordy, w których wystąpiły zmiany.

Podsumowanie

W tym samouczku pokazano, jak utworzyć w pełni edytowalną listę DataList, 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 wartości adresu dostawcy, miasta i kraju/regionu w elemecie DataList s ItemTemplate. Następnie dodaliśmy przyciski Aktualizuj wszystkie powyżej i poniżej pozycji DataList. Po wprowadzeniu zmian przez użytkownika i kliknięciu jednego z przycisków DataListItem Aktualizuj wszystkie zostaną wyliczone znaki s i zostanie wykonane wywołanie SuppliersBLL metody klasy UpdateSupplierAddress .

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 24 godzinach. Można go uzyskać 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 omówiona przez wielu przydatnych recenzentów. Recenzenci z tego samouczka to Zack Jones i Ken Pespisa. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.