Scott MitchellのASP.NET 2.0データチュートリアルの37:一括更新

28821 ワード

テキスト  | このチュートリアルのエンコーディング例をダウンロードします | このチュートリアルのPDF版をダウンロード

ガイド人


先にitemレベルのDataListの作成方法を学びました.編集可能なGridViewと同様に、各DataListのitemにはEdit buttonが含まれており、クリックするとitemが編集可能になります.itemレベルの編集は、たまに更新する必要がある場合は問題ありませんが、ユーザーが大量のレコードを編集する必要がある場合があります.ユーザーが多くのレコードを編集する必要がある場合、彼はEditをクリックし続け、修正し、Updateをクリックしなければなりません.これらの大量のクリックは彼の仕事の効率を妨げます.このような場合、すべてのitemが編集モードにあり、すべての値が「Update All」buttonをクリックすることで更新できる完全に編集可能なDataListを提供することが好ましい.図1を参照.
図1:完全編集可能なDataListのすべてのitemを変更できる
この章では、supplierのaddressを更新する機能を提供する完全に編集可能なDataListを作成する方法について説明します.

ステップ1:DataListのItemTemplateで編集可能なユーザーインタフェースを作成する


標準のitemレベルで編集されたDataListを作成するときに、2つのtemplateを使用しました.
  • ItemTemplate-読み取り専用のユーザインタフェースを含む(Labelを使用して各productのnameとpriceを表示する).
  • EditItemTemplate-編集されたユーザインタフェース(2つのTextBox)を含む.

  • DataListのEditItemIndex属性は、ある場合には、どのDataListItemがEditItemTemplateを使用して表示されるかを示します.すなわち、ItemIndexの値がDataListのEditItemIndexに等しいDataListItemは、EditItemTemplateを用いて示される.一度に1つのitemのみを編集する場合、このモードはよく動作しますが、完全に編集可能なDataListを作成する場合は適用されません.完全に編集可能なDataListでは、すべてのDataListItemを編集可能なインタフェースで表示する必要があります.最も簡単な方法はItemTemplateで編集可能なインタフェースを定義することです.supplierのaddress情報を修正する場合、編集可能なインタフェースではsupplierがテキストとして表現され、address、city、countryの値はTextBoxで表されます.まずBatchUpdateを開く.aspxページでは、DataListを追加し、IDをSuppliersに設定します.Smart LabelでSuppliersDataSourceという名前のObjectDataSourceコントロールを追加します.
    図2:SuppliersDataSourceという名前のObjectDataSourceを作成する
    SuppliersBLLクラスのGetSuppliers()メソッドを使用してObjectDataSourceを構成します(図3参照).前章のように、ObjectDataSourceではなくBLLを直接使用してsupplier情報を更新します.UPDATEタブでNoneを選択します(図4参照).
    図3:GetSuppliers()メソッドを使用してObjectDataSourceを構成する
    図4:UPDATEタグをNoneとする
    ウィザードが完了すると、Visual Studioは、各データフィールドをLabelに表示するために、DataListのItemTemplateを自動的に生成します.このtemplateを変更して編集インタフェースを提供する必要があります.ItemTemplateは、デザイナでDataListのSmart LabelのEdit Templatesまたは宣言構文を直接書くことでカスタマイズできます.編集インタフェースを作成し、supplierのnameをテキスト、address、city、countryをTextBoxとして表現します.これらを完了したら、あなたの宣言コードは以下とあまり差がないはずです.
    ASP.NET
    1
    
                2
    
                3
    
                4
    
                5
    
                6
    
                7
    
                8
    
                9
    
                10
    
                11
    
                12
    
                13
    
                14
    
                15
    
                16
    
                17
    
                18
    
                19
    
                20
    
                21
    
                22
    
                23
    
                24
    
                25
    
                26
    
                27
    
                28
    
                29
    
                30
    
                31
    
                32
    
                33
    
                34
    
                
    <asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID"
    
                DataSourceID="SuppliersDataSource">
    
                <ItemTemplate>
    
                <h4><asp:Label ID="CompanyNameLabel" runat="server" Text='<%# Eval("CompanyName") %>'>
    
                </asp:Label></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>
    
                

    注意:前章と同様に、DataListのview stateをオンにする必要があります.ItemTemplateでは2つの新しいCSSクラス、SupplierPropertyLabelとSupplierPropertyValueを使用しました.それらのスタイル設定はProductsPropertyLabelとProductPropertyValue CSSクラスと同じで、Stylesに追加されています.cssで.
    CSS
    1
    
                2
    
                3
    
                4
    
                5
    
                6
    
                7
    
                8
    
                9
    
                10
    
                
    .ProductPropertyLabel, .SupplierPropertyLabel
    
                {
    
                font-weight: bold;
    
                text-align: right;
    
                }
    
                .ProductPropertyValue, .SupplierPropertyValue
    
                {
    
                padding-right: 35px;
    
                }
    
                

    これらを完了したら、ページを参照します.図5に示すように、各DataListのitemはsupplier nameをテキストで表示し、address,city,countryをTextBoxで表示する.
    図5:DataListの各Supplierは編集可能

    ステップ2:「Update All」Buttonを追加


    図5に示す情報は、まだUpdateボタンが提供されていない.完全に編集可能なDataListには、前のようにitemごとにbuttonが1つ含まれるのではなく、「Update All」ボタンが1つしか含まれていないはずです.「Update All」をクリックすると、DataListのすべてのレコードが更新されます.この章では、2つの「Update All」buttonを追加します.1つはページの上にあり、1つは下にあります(両方とも同じ機能を提供します).まず、DataListにUpdateAll 1というIDのButtonを追加します.そして、DataListの下にUpdataAll 2としてIDのButtonを追加する.両方のButtonのTextは「Update All」に設定されています.最後に2つのButtonのClickイベントのevent handlerを作成します.「UpdateAllSupplier Address」というメソッドを作成し、イベント処理で呼び出します.(2つのイベント処理で同じコードをコピーするのではなく)
    C#
    1
    
                2
    
                3
    
                4
    
                5
    
                6
    
                7
    
                8
    
                9
    
                10
    
                11
    
                12
    
                13
    
                14
    
                
    protected void UpdateAll1_Click(object sender, EventArgs e)
    
                {
    
                UpdateAllSupplierAddresses();
    
                }
    
                protected void UpdateAll2_Click(object sender, EventArgs e)
    
                {
    
                UpdateAllSupplierAddresses();
    
                }
    
                private void UpdateAllSupplierAddresses()
    
                {
    
                // TODO: Write code to update _all_ of the supplier addresses in the DataList
    
                }
    
                

    【図6】「Update All」buttonを追加したページ.
    図6:2つの「Update All」Buttonをページに追加

    ステップ3:すべてのSuppliersのAddress情報を更新


    すべてのitemを編集可能なインタフェースとして表示し、「Update All」buttonを追加した後、残りはコードを書いて一括更新を実行することです.DataListのitemを便利にし、SuppliersBLLクラスのUpdateSupplierAddressメソッドを呼び出す必要があります.
    DataListItemのセットには、DataListのItems propertyからアクセスできます.DataListItemの参照により、DataKeysコレクションから関連するSuppliserIDを取得し、ItemTemplateのTextBoxを参照できます.次のコードを参照してください.
    C#
    1
    
                2
    
                3
    
                4
    
                5
    
                6
    
                7
    
                8
    
                9
    
                10
    
                11
    
                12
    
                13
    
                14
    
                15
    
                16
    
                17
    
                18
    
                19
    
                20
    
                21
    
                22
    
                23
    
                24
    
                25
    
                26
    
                27
    
                28
    
                29
    
                
    private void UpdateAllSupplierAddresses()
    
                {
    
                // Create an instance of the SuppliersBLL class
    
                SuppliersBLL suppliersAPI = new SuppliersBLL();
    
                // Iterate through the DataList's items
    
                foreach (DataListItem item in Suppliers.Items)
    
                {
    
                // Get the supplierID from the DataKeys collection
    
                int supplierID = Convert.ToInt32(Suppliers.DataKeys[item.ItemIndex]);
    
                // Read in the user-entered values
    
                TextBox address = (TextBox)item.FindControl("Address");
    
                TextBox city = (TextBox)item.FindControl("City");
    
                TextBox country = (TextBox)item.FindControl("Country");
    
                string addressValue = null, cityValue = null, countryValue = null;
    
                if (address.Text.Trim().Length > 0)
    
                addressValue = address.Text.Trim();
    
                if (city.Text.Trim().Length > 0)
    
                cityValue = city.Text.Trim();
    
                if (country.Text.Trim().Length > 0)
    
                countryValue = country.Text.Trim();
    
                // Call the SuppliersBLL class's UpdateSupplierAddress method
    
                suppliersAPI.UpdateSupplierAddress
    
                (supplierID, addressValue, cityValue, countryValue);
    
                }
    
                }
    
                

    ユーザが「Update All」buttonをクリックすると、各Supplier Data ListのDataListItemは、UpdateAllSupplier Addressメソッドを実行し、SuppliersBLLクラスのUpdateSupplier Addressメソッドを呼び出し、関連する値を渡す.address、cityまたはcountryに値を入力しない場合、UpdateSupplierAddressは空の値(空の文字列ではない)を受信し、関連するフィールドの結果はdatabase NULLになります.
    注意:一括更新が完了したら確認情報を提供するために、表示されるステータスLabelを追加できます.

    Addressesが変更されたレコードのみ更新


    The batch update algorithm used for this tutorial calls the UpdateSupplierAddress method for every supplier in the DataList, regardless of whether their address information has been changed. While such blind updates aren’t usually a performance issue, they can lead to superfluous records if you’re auditing changes to the database table. For example, if you use triggers to record all UPDATE s to the Suppliers table to an auditing table, every time a user clicks the “Update All” button a new audit record will be created for each supplier in the system, regardless of whether the user made any changes.この章で使用する一括更新法則は、address情報が変更されたかどうかにかかわらず、各DataListのsupplierにUpdateSupplier Addressメソッドを呼び出す.このような盲目的な更新では、パフォーマンスに問題はありませんが、データベース・テーブルの監査を行うと、多くの余分なレコードが発生します.ユーザーが「Update All」buttonをクリックするたびに、ユーザーが変更したかどうかにかかわらず、システムにはsupplierごとに新しい監査記録が生成されます.ADO.NETのDateTableクラスとDataAdapterクラスは、変更、削除、または新規のレコードのみを一括更新することをサポートするように設計されています.DataTableの各rowにはRowState propertyがあり、このrowがDataTableに追加されたか、削除されたか、変更されたか、変更されていないかを示しています.DataTableが生成されたばかりの場合、すべてのrowは変更されていないとマークされ、rowの列を変更するとrowは変更されたとマークされます.SuppliersBLLクラスでは、まずsupplierのレコードをSuppliersDataTableに読み込み、Address、City、Country列の値を設定して、指定したsupplierの情報を更新します.次のコードを参照してください.
    C#
    1
    
                2
    
                3
    
                4
    
                5
    
                6
    
                7
    
                8
    
                9
    
                10
    
                11
    
                12
    
                13
    
                14
    
                15
    
                16
    
                17
    
                18
    
                19
    
                20
    
                21
    
                22
    
                23
    
                24
    
                25
    
                26
    
                27
    
                28
    
                29
    
                30
    
                31
    
                32
    
                33
    
                
    public bool UpdateSupplierAddress
    
                (int supplierID, string address, string city, string country)
    
                {
    
                Northwind.SuppliersDataTable suppliers =
    
                Adapter.GetSupplierBySupplierID(supplierID);
    
                if (suppliers.Count == 0)
    
                // no matching record found, return false
    
                return false;
    
                else
    
                {
    
                Northwind.SuppliersRow supplier = suppliers[0];
    
                if (address == null)
    
                supplier.SetAddressNull();
    
                else
    
                supplier.Address = address;
    
                if (city == null)
    
                supplier.SetCityNull();
    
                else
    
                supplier.City = city;
    
                if (country == null)
    
                supplier.SetCountryNull();
    
                else
    
                supplier.Country = country;
    
                // Update the supplier Address-related information
    
                int rowsAffected = Adapter.Update(supplier);
    
                // Return true if precisely one row was updated, 
    
                // otherwise false
    
                return rowsAffected == 1;
    
                }
    
                }
    
                

    このコードは、値が変更されたかどうかにかかわらず、入力されたaddress、city、countryの値をSuppliersDataTableのSuppliersRowに割り当てます.この変更により、SuppliersRowのRowStateプロパティが変更されたとマークされます.DALのUpdateメソッドが呼び出されると、SupplierRowが変更されていることがわかり、UPDATEコマンドがデータベースに送信されます.
    しかし,我々がこの方法に追加したコードは,既に存在する値と異なる場合にのみ,伝達されたaddress,city,countryの値をSuppliersRowに与えることを想像する.address、city、countryが変更されていない場合、SupplierRowのRowStateは変更されていないとマークされます.この結果、DALのUpdateメソッドが呼び出されると、SuppliersRowは変更されず、データベースは呼び出されません.前の盲目的な割り当ての代わりに、次のコードを使用します.
    C#
    1
    
                2
    
                3
    
                4
    
                5
    
                6
    
                7
    
                8
    
                9
    
                10
    
                11
    
                12
    
                13
    
                14
    
                15
    
                16
    
                17
    
                18
    
                
    // Only assign the values to the SupplierRow's column values if they differ
    
                if (address == null && !supplier.IsAddressNull())
    
                supplier.SetAddressNull();
    
                else if ((address != null && supplier.IsAddressNull()) ||
    
                (!supplier.IsAddressNull() && string.Compare(supplier.Address, address) != 0))
    
                supplier.Address = address;
    
                if (city == null && !supplier.IsCityNull())
    
                supplier.SetCityNull();
    
                else if ((city != null && supplier.IsCityNull()) ||
    
                (!supplier.IsCityNull() && string.Compare(supplier.City, city) != 0))
    
                supplier.City = city;
    
                if (country == null && !supplier.IsCountryNull())
    
                supplier.SetCountryNull();
    
                else if ((country != null && supplier.IsCountryNull()) ||
    
                (!supplier.IsCountryNull() && string.Compare(supplier.Country, country) != 0))
    
                supplier.Country = country;
    
                

    これらのコードを追加すると、DALのUpdateメソッドはaddress関連の値を変更したレコードだけでUPDATEコマンドをデータベースに送信します.もちろん、入力されたフィールドとデータベースデータの違いを追跡することもできます.そうでなければ、DALのUpdateメソッドを呼び出す必要はありません.この方法は、直接のデータベースコマンドを使用する場合に非常に有効です.直接のデータベースコマンドは、SuppliersRowをチェックしてデータベースを呼び出す必要があるかどうかを決定しないからです.注意:UpdateSupplier Addressメソッドが呼び出されるたびに、更新するレコードの情報を取得するためにデータベースが呼び出されます.データが変更された場合、データベースを呼び出してデータを更新します.このプロセスは、BatchUpdateを含むEmployeesDataTableを受け入れる、リロードされたUpdateSupplier Addressメソッドを作成することによって最適化することができる.aspxページのすべての変更.その後、Suppliersテーブルのすべてのレコードを取得するためにデータベースが呼び出されます.結果セットでは修正されたレコードだけが更新されます.

    まとめ


    この章では、完全に編集可能なDataListを作成する方法について説明します.ユーザーは、複数のsupplierのaddress情報を迅速に変更できます.まず、編集インタフェースであるaddressを定義し、cityとcountryはTextBoxで表されます.DataListのItemTemplateにあります.その後、DataListの上下に「Update All」buttonを1つずつ追加しました.ユーザが修正した後、いずれかをクリックすると、各DataListItemはSuppliersBLLクラスのUpdateSupplier Addressメソッドを呼び出します.
    プログラミングが楽しいことを祈ります!