일괄 처리 업데이트 수행(VB)

작성자 : Scott Mitchell

PDF 다운로드

페이지에서 "모두 업데이트" 단추를 클릭하여 모든 항목이 편집 모드에 있고 해당 값을 저장할 수 있는 완전히 편집 가능한 DataList를 만드는 방법을 알아봅니다.

소개

이전 자습서에서는 항목 수준 DataList를 만드는 방법을 검토했습니다. 표준 편집 가능한 GridView와 마찬가지로 DataList의 각 항목에는 항목을 편집할 수 있도록 하는 편집 단추가 포함되어 있습니다. 이 항목 수준 편집은 가끔 업데이트되는 데이터에 적합하지만 특정 사용 사례 시나리오에서는 사용자가 많은 레코드를 편집해야 합니다. 사용자가 수십 개의 레코드를 편집해야 하고 편집을 클릭하고 변경한 다음 각 레코드에 대해 업데이트를 클릭해야 하는 경우 클릭 양이 생산성을 저해할 수 있습니다. 이러한 상황에서 더 나은 옵션은 모든 항목이 편집 모드에 있고 페이지에서 모두 업데이트 단추를 클릭하여 값을 편집할 수 있는 완전히 편집 가능한 DataList를 제공하는 것입니다(그림 1 참조).

완전히 편집 가능한 DataList의 각 항목을 수정할 수 있습니다.

그림 1: 완전히 편집 가능한 DataList의 각 항목을 수정할 수 있습니다(전체 크기 이미지를 보려면 클릭).

이 자습서에서는 사용자가 완전히 편집 가능한 DataList를 사용하여 공급자 주소 정보를 업데이트할 수 있도록 하는 방법을 살펴봅니다.

1단계: DataList의 ItemTemplate에서 편집 가능한 사용자 인터페이스 만들기

이전 자습서에서는 표준 항목 수준 편집 가능한 DataList를 만들 때 다음 두 가지 템플릿을 사용했습니다.

  • ItemTemplate 에는 읽기 전용 사용자 인터페이스(각 제품의 이름과 가격을 표시하기 위한 레이블 웹 컨트롤)가 포함되어 있습니다.
  • EditItemTemplate 에는 편집 모드 사용자 인터페이스(두 개의 TextBox 웹 컨트롤)가 포함되어 있습니다.

DataList의 EditItemIndex 속성은 를 사용하여 렌더링되는 항목 DataListItem (있는 경우)을 지정합니다 EditItemTemplate. 특히 해당 값이 DataListItemItemIndex DataList의 EditItemIndex 속성과 일치하는 은 를 사용하여 EditItemTemplate렌더링됩니다. 이 모델은 한 번에 하나의 항목만 편집할 수 있지만 완전히 편집 가능한 DataList를 만들 때 떨어져 있는 경우에 잘 작동합니다.

완전히 편집 가능한 DataList의 경우 편집 가능한 인터페이스를 DataListItem 사용하여 모든 를 렌더링하려고 합니다. 이 작업을 수행하는 가장 간단한 방법은 에서 편집 가능한 인터페이스를 정의하는 것입니다 ItemTemplate. 공급자 주소 정보를 수정하기 위해 편집 가능한 인터페이스는 공급자 이름을 텍스트로 포함하고 주소, 도시 및 국가/지역 값에 대한 TextBoxes를 포함합니다.

먼저 페이지를 열고 BatchUpdate.aspx DataList 컨트롤을 추가하고 속성을 IDSuppliers로 설정합니다. DataList의 스마트 태그에서 라는 SuppliersDataSource새 ObjectDataSource 컨트롤을 추가하도록 선택합니다.

SuppliersDataSource라는 새 ObjectDataSource 만들기

그림 2: 새 ObjectDataSource 이름 SuppliersDataSource 만들기(전체 크기 이미지를 보려면 클릭)

클래스의 GetSuppliers() 메서드를 사용하여 데이터를 검색하도록 ObjectDataSource를 SuppliersBLL 구성합니다(그림 3 참조). 이전 자습서와 마찬가지로 ObjectDataSource를 통해 공급자 정보를 업데이트하는 대신 비즈니스 논리 계층으로 직접 작업합니다. 따라서 업데이트 탭에서 드롭다운 목록을 (없음)으로 설정합니다(그림 4 참조).

GetSuppliers() 메서드를 사용하여 공급업체 정보 검색

그림 3: 메서드를 GetSuppliers() 사용하여 공급업체 정보 검색(전체 크기 이미지를 보려면 클릭)

업데이트 탭에서 Drop-Down 목록을 (없음)으로 설정합니다.

그림 4: 업데이트 탭에서 Drop-Down 목록을 (없음)으로 설정합니다(전체 크기 이미지를 보려면 클릭).

마법사를 완료한 후 Visual Studio는 DataList를 ItemTemplate 자동으로 생성하여 레이블 웹 컨트롤의 데이터 원본에서 반환된 각 데이터 필드를 표시합니다. 편집 인터페이스를 대신 제공하려면 이 템플릿을 수정해야 합니다. 는 ItemTemplate DataList의 스마트 태그에서 템플릿 편집 옵션을 사용하거나 선언적 구문을 통해 직접 Designer 통해 사용자 지정할 수 있습니다.

잠시 시간을 내어 공급자 이름을 텍스트로 표시하지만 공급자 주소, 도시 및 국가/지역 값에 대한 TextBoxes를 포함하는 편집 인터페이스를 만듭니다. 이러한 변경을 수행한 후 페이지의 선언적 구문은 다음과 유사하게 표시됩니다.

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

참고

이전 자습서와 마찬가지로 이 자습서의 DataList는 뷰 상태를 사용하도록 설정해야 합니다.

에서 클래스에 ItemTemplate 추가 Styles.css 되고 및 CSS 클래스 SupplierPropertyLabelSupplierPropertyValue동일한 스타일 설정을 ProductPropertyLabel 사용하도록 구성된 두 개의 새 CSS 클래스 및 ProductPropertyValue 를 사용합니다.

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

이러한 변경 내용을 변경한 후 브라우저를 통해 이 페이지를 방문하세요. 그림 5와 같이 각 DataList 항목은 공급자 이름을 텍스트로 표시하고 TextBoxes를 사용하여 주소, 도시 및 국가/지역을 표시합니다.

DataList의 각 공급자는 편집 가능

그림 5: DataList의 각 공급자는 편집 가능(전체 크기 이미지를 보려면 클릭)

2단계: 모두 업데이트 단추 추가

그림 5의 각 공급업체에는 TextBox에 표시되는 주소, 도시 및 국가/지역 필드가 있지만 현재는 업데이트 단추를 사용할 수 없습니다. 완전히 편집 가능한 DataLists를 사용하여 항목당 업데이트 단추를 사용하는 대신 일반적으로 페이지에는 DataList의 모든 레코드를 업데이트하는 모든 업데이트 단추가 하나 있습니다. 이 자습서에서는 두 개의 모두 업데이트 단추를 추가해 보겠습니다. 하나는 페이지 맨 위에, 다른 하나는 아래쪽에 추가합니다(두 단추를 클릭하면 동일한 효과가 있음).

먼저 DataList 위에 단추 웹 컨트롤을 추가하고 해당 ID 속성을 로 UpdateAll1설정합니다. 다음으로 DataList 아래에 두 번째 단추 웹 컨트롤을 추가하고 을 IDUpdateAll2설정합니다. 두 단추의 Text 속성을 모두 업데이트로 설정합니다. 마지막으로 두 Buttons 이벤트에 대한 이벤트 처리기를 만듭니다 Click . 각 이벤트 처리기에서 업데이트 논리를 복제하는 대신, 이벤트 처리기가 이 세 번째 메서드를 호출하기만 하면 해당 논리를 세 번째 메서드 UpdateAllSupplierAddresses로 리팩터링해 보겠습니다.

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

그림 6은 모두 업데이트 단추가 추가된 후의 페이지를 보여 줍니다.

두 개의 모든 업데이트 단추가 페이지에 추가되었습니다.

그림 6: 두 개의 모든 업데이트 단추가 페이지에 추가되었습니다(전체 크기 이미지를 보려면 클릭).

3단계: 모든 공급업체 주소 정보 업데이트

모든 DataList 항목이 편집 인터페이스를 표시하고 모두 업데이트 단추가 추가되면 나머지 모든 항목은 일괄 업데이트를 수행하기 위해 코드를 작성하는 것입니다. 특히 DataList의 항목을 반복하고 각 항목에 대한 클래스의 UpdateSupplierAddress 메서드를 SuppliersBLL 호출해야 합니다.

DataList의 DataListItem 속성을 통해 DataList를 구성하는 인스턴스의 Items컬렉션에 액세스할 수 있습니다. 에 대한 참조를 DataListItem사용하여 컬렉션에서 해당 SupplierID 를 잡고 다음 코드와 DataKeys 같이 내에서 TextBox 웹 컨트롤을 ItemTemplate 프로그래밍 방식으로 참조할 수 있습니다.

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

사용자가 모두 업데이트 단추 중 하나를 클릭하면 메서드는 UpdateAllSupplierAddresses DataList의 각 SuppliersDataListItem 단추를 반복하고 클래스의 UpdateSupplierAddress 메서드를 호출 SuppliersBLL 하여 해당 값을 전달합니다. 주소, 도시 또는 국가/지역 패스에 대해 입력되지 않은 값은 에 대한 NothingUpdateSupplierAddress 값(빈 문자열이 아닌)이며, 이로 인해 기본 레코드 필드에 대한 데이터베이스 NULL 가 생성됩니다.

참고

향상된 기능으로 일괄 업데이트가 수행된 후 일부 확인 메시지를 제공하는 페이지에 상태 레이블 웹 컨트롤을 추가할 수 있습니다.

수정된 주소만 업데이트

이 자습서에 사용되는 일괄 업데이트 알고리즘은 주소 정보가 변경되었는지 여부에 관계없이 DataList의 모든 공급자에 대한 메서드를 호출 UpdateSupplierAddress 합니다. 이러한 블라인드 업데이트는 일반적으로 성능 문제가 아니지만 데이터베이스 테이블의 변경 내용을 감사하는 경우 불필요한 레코드로 이어질 수 있습니다. 예를 들어 트리거를 사용하여 테이블에 모든 UPDATESuppliers 감사 테이블에 기록하는 경우 사용자가 모두 업데이트 단추를 클릭할 때마다 사용자가 변경했는지 여부에 관계없이 시스템의 각 공급자에 대해 새 감사 레코드가 만들어집니다.

ADO.NET DataTable 및 DataAdapter 클래스는 수정, 삭제 및 새 레코드만 데이터베이스 통신을 초래하는 일괄 업데이트를 지원하도록 설계되었습니다. DataTable의 각 행에는 RowState 행이 DataTable에 추가되었는지, 해당 행에서 삭제되었는지, 수정되었는지 또는 변경되지 않은 상태로 유지되는지를 나타내는 속성이 있습니다. DataTable이 처음 채워지면 모든 행이 변경되지 않은 것으로 표시됩니다. 행 열의 값을 변경하면 행이 수정된 것으로 표시됩니다.

SuppliersBLL 클래스에서 먼저 단일 공급자 레코드 SuppliersDataTable 를 읽어 지정된 공급자의 주소 정보를 로 업데이트한 다음, 다음 코드를 사용하여 , CityCountry 열 값을 설정합니다Address.

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

이 코드는 값이 변경되었는지 여부에 관계없이 전달된 주소, 도시 및 국가/지역 값을 SuppliersRow 의 에 SuppliersDataTable 순진하게 할당합니다. 이러한 수정으로 인해 의 RowState 속성이 SuppliersRow 수정된 것으로 표시됩니다. 데이터 액세스 계층의 Update 메서드가 호출되면 가 수정되어 데이터베이스에 UPDATE 명령을 보내는 것을 볼 SupplierRow 수 있습니다.

그러나 전달된 주소, 도시 및 국가/지역 값이 기존 값과 다른 SuppliersRow 경우에만 할당하기 위해 이 메서드에 코드를 추가했다고 가정해 보겠습니다. 주소, 구/군/시 및 국가/지역이 기존 데이터와 동일한 경우 변경되지 않으며 가 SupplierRowRowState 변경되지 않은 것으로 표시됩니다. 결과적으로 DAL의 Update 메서드가 호출될 때 가 수정되지 않았기 때문에 SuppliersRow 데이터베이스 호출이 이루어지지 않습니다.

이 변경을 적용하려면 전달된 주소, 도시 및 국가/지역 값을 맹목적으로 할당하는 문을 다음 코드로 바꿉니다.

' 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

이 코드가 추가되면 DAL의 Update 메서드는 주소 관련 값이 변경된 레코드에 대해서만 문을 데이터베이스에 보냅니 UPDATE 다.

또는 전달된 주소 필드와 데이터베이스 데이터 간에 차이점이 있는지 여부를 추적할 수 있으며, 없는 경우 DAL 메서드에 대한 Update 호출을 무시하기만 하면 됩니다. 이 방법은 DB 직접 메서드를 사용하는 경우 DB 직접 메서드가 데이터베이스 호출이 실제로 필요한지 여부를 확인할 수 있는 RowState instance 전달 SuppliersRow 되지 않으므로 잘 작동합니다.

참고

메서드가 UpdateSupplierAddress 호출될 때마다 데이터베이스를 호출하여 업데이트된 레코드에 대한 정보를 검색합니다. 그런 다음 데이터가 변경되면 데이터베이스에 대한 또 다른 호출을 통해 테이블 행을 업데이트합니다. 이 워크플로는 페이지의 모든 변경 내용 BatchUpdate.aspx 이 있는 instance 허용하는 EmployeesDataTable 메서드 오버로드를 만들어 UpdateSupplierAddress 최적화할 수 있습니다. 그런 다음 데이터베이스를 한 번 호출하여 테이블에서 모든 레코드 Suppliers 를 가져올 수 있습니다. 그런 다음 두 결과 집합을 열거할 수 있으며 변경이 발생한 레코드만 업데이트할 수 있습니다.

요약

이 자습서에서는 사용자가 여러 공급자의 주소 정보를 신속하게 수정할 수 있도록 완전히 편집 가능한 DataList를 만드는 방법을 알아보았습니다. 먼저 DataList ItemTemplate의 에서 공급자 주소, 도시 및 국가/지역 값에 대한 TextBox 웹 컨트롤 편집 인터페이스를 정의했습니다. 다음으로 DataList 위와 아래에 모두 업데이트 단추가 추가되었습니다. 사용자가 변경한 후 모두 업데이트 단추 DataListItem 중 하나를 클릭하면 가 열거되고 클래스의 UpdateSupplierAddress 메서드가 SuppliersBLL 호출됩니다.

행복한 프로그래밍!

저자 정보

7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술로 작업해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 유어셀프 ASP.NET 24시간 만에 2.0입니다. 그는 에서mitchell@4GuysFromRolla.com 또는 에서 찾을 http://ScottOnWriting.NET수있는 자신의 블로그를 통해 도달 할 수 있습니다.

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 잭 존스와 켄 페스피사였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 에 줄을 놓습니다 mitchell@4GuysFromRolla.com.