다음을 통해 공유


일괄 삭제(VB)

작성자: 스콧 미첼

PDF 다운로드

단일 작업에서 여러 데이터베이스 레코드를 삭제하는 방법을 알아봅니다. 사용자 인터페이스 계층에서는 이전 자습서에서 만든 향상된 GridView를 기반으로 합니다. 데이터 액세스 계층에서 트랜잭션 내에서 여러 삭제 작업을 래핑하여 모든 삭제가 성공하거나 모든 삭제가 롤백되도록 합니다.

소개

이전 자습서에서는 완전히 편집 가능한 GridView를 사용하여 일괄 처리 편집 인터페이스를 만드는 방법을 살펴보했습니다. 사용자가 일반적으로 많은 레코드를 한 번에 편집하는 경우 일괄 처리 편집 인터페이스에는 훨씬 적은 포스트백 및 키보드-마우스 컨텍스트 스위치가 필요하므로 최종 사용자의 효율성이 향상됩니다. 이 기술은 사용자가 한 번의 이동으로 많은 레코드를 삭제하는 것이 일반적인 페이지에도 마찬가지로 유용합니다.

온라인 전자 메일 클라이언트를 사용한 사람은 이미 가장 일반적인 일괄 처리 삭제 인터페이스 중 하나에 익숙합니다. 그리드의 각 행에 있는 확인란에 해당하는 모든 선택 항목 삭제 단추가 있습니다(그림 1 참조). 이 자습서는 웹 기반 인터페이스와 일련의 레코드를 단일 원자성 작업으로 삭제하는 방법을 만드는 이전 자습서의 모든 작업을 이미 수행했기 때문에 다소 짧습니다. GridView에 확인란 열 추가 자습서에서는 확인란 열이 있는 GridView를 만들었으며, 트랜잭션으로 데이터베이스 수정 감싸기 자습서에서는 BLL에서 트랜잭션을 사용하여 List<T>ProductID 값을 삭제하는 메서드를 만들었습니다. 이 자습서에서는 이전 경험을 토대로 통합하여 잘 작동하는 일괄 삭제 예제를 만듭니다.

각 행에 확인란이 포함됨

그림 1: 각 행에 확인란이 포함됨(전체 크기 이미지를 보려면 클릭)

1단계: 일괄 처리 삭제 인터페이스 만들기

확인란의 GridView 열 추가 자습서에서 일괄 삭제 인터페이스를 이미 만들었으므로, 처음부터 만들기보다는 BatchDelete.aspx로 간단히 복사하면 됩니다. BatchDelete.aspx 페이지를 BatchData 폴더에서 열고, CheckBoxField.aspx 페이지를 EnhancedGridView 폴더에서 여는 것으로 시작합니다. CheckBoxField.aspx 페이지에서 소스 보기로 이동하여 <asp:Content> 태그 사이의 마크업을 그림 2에 표시된 대로 복사합니다.

CheckBoxField.aspx 선언적 태그를 클립보드에 복사

그림 2: 클립보드에 선언적 태그 CheckBoxField.aspx 복사(전체 크기 이미지를 보려면 클릭)

그런 다음 원본 보기 BatchDelete.aspx 로 이동하여 태그 내에 <asp:Content> 클립보드의 내용을 붙여넣습니다. 코드 숨김 클래스 CheckBoxField.aspx.vb 내에서 코드 숨김 클래스 BatchDelete.aspx.vb 안으로, 코드 숨김 클래스의 코드를 복사하여 붙여넣기 하세요. (DeleteSelectedProducts 버튼 이벤트 처리기, Click 메서드 및 ToggleCheckState 이벤트 처리기, ClickCheckAll 버튼을 포함합니다.) 이 콘텐츠를 BatchDelete.aspx 복사한 후 페이지의 코드 숨김 클래스에는 다음 코드가 포함되어야 합니다.

Partial Class BatchData_BatchDelete
    Inherits System.Web.UI.Page
    Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
        Handles DeleteSelectedProducts.Click
        
        Dim atLeastOneRowDeleted As Boolean = False
        ' Iterate through the Products.Rows property
        For Each row As GridViewRow In Products.Rows
            ' Access the CheckBox
            Dim cb As CheckBox = row.FindControl("ProductSelector")
            If cb IsNot Nothing AndAlso cb.Checked Then
                ' Delete row! (Well, not really...)
                atLeastOneRowDeleted = True
                ' First, get the ProductID for the selected row
                Dim productID As Integer = _
                    Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
                ' "Delete" the row
                DeleteResults.Text &= String.Format _
                    ("This would have deleted ProductID {0}<br />", productID)
                '... To actually delete the product, use ...
                ' Dim productAPI As New ProductsBLL
                ' productAPI.DeleteProduct(productID)
                '............................................
            End If
        Next
        ' Show the Label if at least one row was deleted...
        DeleteResults.Visible = atLeastOneRowDeleted
    End Sub
    Private Sub ToggleCheckState(ByVal checkState As Boolean)
        ' Iterate through the Products.Rows property
        For Each row As GridViewRow In Products.Rows
            ' Access the CheckBox
            Dim cb As CheckBox = row.FindControl("ProductSelector")
            If cb IsNot Nothing Then
                cb.Checked = checkState
            End If
        Next
    End Sub
    Protected Sub CheckAll_Click(sender As Object, e As EventArgs) _
        Handles CheckAll.Click
        ToggleCheckState(True)
    End Sub
    Protected Sub UncheckAll_Click(sender As Object, e As EventArgs) _
        Handles UncheckAll.Click
        ToggleCheckState(False)
    End Sub
End Class

선언적 태그와 소스 코드를 복사한 후, 브라우저를 통해 BatchDelete.aspx을(를) 확인하면서 잠시 테스트하세요. GridView에서 처음 10개 제품이 나열되며, 각 행에는 제품 이름, 범주, 가격 및 확인란이 포함됩니다. 모두 확인, 모두 선택 취소 및 선택한 제품 삭제의 세 가지 단추가 있어야 합니다. [모두 확인] 단추를 클릭하면 모든 확인란이 선택되며[ 모두 선택 취소]는 모든 확인란의 선택을 취소합니다. 선택한 제품 삭제를 클릭하면 선택한 제품의 값이 나열 ProductID 되지만 실제로는 제품을 삭제하지 않는 메시지가 표시됩니다.

CheckBoxField.aspx의 인터페이스가 BatchDeleting.aspx로 전송되었습니다

그림 3: 인터페이스 CheckBoxField.aspx 가 이동 BatchDeleting.aspx 되었습니다(전체 크기 이미지를 보려면 클릭).

2단계: 트랜잭션을 사용하여 확인된 제품 삭제

일괄 삭제 인터페이스가 성공적으로 BatchDeleting.aspx에 복사됐으니, 코드 업데이트를 통해 클래스 DeleteProductsWithTransaction의 메서드 ProductsBLL을 사용하여 선택한 제품 삭제 버튼이 확인된 제품을 삭제할 수 있도록 해야 합니다. 트랜잭션 내 데이터베이스 수정 래핑 자습서에서 추가된 이 메서드는 List(Of T) 값들의 ProductID를 입력으로 받아들이며, 트랜잭션 범위 내에서 각 해당하는 ProductID를 삭제합니다.

DeleteSelectedProducts Button의 Click 이벤트 처리기는 현재 다음 For Each 루프를 사용하여 각 GridView 행을 반복합니다.

' Iterate through the Products.Rows property
For Each row As GridViewRow In Products.Rows
    ' Access the CheckBox
    Dim cb As CheckBox = row.FindControl("ProductSelector")
    If cb IsNot Nothing AndAlso cb.Checked Then
        ' Delete row! (Well, not really...)
        atLeastOneRowDeleted = True
        ' First, get the ProductID for the selected row
        Dim productID As Integer = _
            Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
        ' "Delete" the row
        DeleteResults.Text &= String.Format _
            ("This would have deleted ProductID {0}<br />", productID)
        '... To actually delete the product, use ...
        ' Dim productAPI As New ProductsBLL
        ' productAPI.DeleteProduct(productID)
        '............................................
    End If
Next

각 행에서 ProductSelector CheckBox 웹 컨트롤이 프로그래밍 방식으로 참조됩니다. 이 옵션을 선택하면 ProductID에 있는 행이 DataKeys 컬렉션에서 검색되고, DeleteResults 레이블의 Text 속성이 업데이트되어 해당 행이 삭제를 위해 선택되었음을 알리는 메시지가 포함됩니다.

위의 코드는 ProductsBLL 클래스의 Delete 메서드 호출이 주석 처리되어 있으므로 실제로 어떤 상품 레코드도 삭제하지 않습니다. 이 삭제 논리를 적용할 경우, 코드는 상품을 삭제하지만 원자적 작업 내에서 실행되지 않습니다. 즉, 시퀀스의 처음 몇 개의 삭제가 성공했지만 나중에 실패한 경우(아마도 외래 키 제약 조건 위반으로 인해) 예외가 throw되지만 이미 삭제된 제품은 삭제된 상태로 유지됩니다.

원자성을 보장하기 위해 ProductsBLL 클래스의 DeleteProductsWithTransaction 메서드를 사용해야 합니다. 이 메서드는 값 목록을 ProductID 허용하므로 먼저 표에서 이 목록을 컴파일한 다음 매개 변수로 전달해야 합니다. 먼저 List(Of T) 유형의 Integer 인스턴스를 만듭니다. For Each 루프 내에서 선택한 제품의 ProductID 값을 이 List(Of T)에 추가해야 합니다. 루프 후에 클래스 List(Of T)ProductsBLL 메서드에 DeleteProductsWithTransaction 전달되어야 합니다. DeleteSelectedProducts 다음 코드로 Button의 Click 이벤트 처리기를 업데이트합니다.

Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
    Handles DeleteSelectedProducts.Click
    
    ' Create a List to hold the ProductID values to delete
    Dim productIDsToDelete As New System.Collections.Generic.List(Of Integer)
    ' Iterate through the Products.Rows property
    For Each row As GridViewRow In Products.Rows
        ' Access the CheckBox
        Dim cb As CheckBox = CType(row.FindControl("ProductSelector"), CheckBox)
        If cb IsNot Nothing AndAlso cb.Checked Then
            ' Save the ProductID value for deletion
            ' First, get the ProductID for the selected row
            Dim productID As Integer = _
                Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
            ' Add it to the List...
            productIDsToDelete.Add(productID)
            ' Add a confirmation message
            DeleteResults.Text &= String.Format _
                ("ProductID {0} has been deleted<br />", productID)
        End If
    Next
    ' Call the DeleteProductsWithTransaction method and show the Label 
    ' if at least one row was deleted...
    If productIDsToDelete.Count > 0 Then
        Dim productAPI As New ProductsBLL()
        productAPI.DeleteProductsWithTransaction(productIDsToDelete)
        DeleteResults.Visible = True
        ' Rebind the data to the GridView
        Products.DataBind()
    End If
End Sub

업데이트된 코드는 List(Of T) (Integer) 형식의 productIDsToDelete을(를) 생성하고 삭제할 ProductID 값들로 채웁니다. 루프 후에 For Each 하나 이상의 제품이 선택된 ProductsBLL 경우 클래스의 DeleteProductsWithTransaction 메서드가 호출되고 이 목록을 전달합니다. DeleteResults 레이블도 표시되고 데이터가 GridView로 다시 조정됩니다(새로 삭제된 레코드가 더 이상 표에 행으로 표시되지 않도록).

그림 4는 삭제를 위해 여러 행이 선택된 후의 GridView를 보여 줍니다. 그림 5는 선택한 제품 삭제 단추를 클릭한 직후의 화면을 보여 줍니다. 그림 5 ProductID 에서는 삭제된 레코드의 값이 GridView 아래의 레이블에 표시되고 해당 행은 더 이상 GridView에 없습니다.

선택한 제품이 삭제됩니다.

그림 4: 선택한 제품이 삭제됩니다(전체 크기 이미지를 보려면 클릭).

삭제된 제품 ProductID 값이 GridView 아래에 나열됩니다.

그림 5: 삭제된 제품 ProductID 값이 GridView 아래에 나열됩니다(전체 크기 이미지를 보려면 클릭).

비고

메서드의 DeleteProductsWithTransaction 원자성을 테스트하려면 테이블에 제품에 Order Details 대한 항목을 수동으로 추가한 다음 해당 제품(다른 제품과 함께)을 삭제하려고 시도합니다. 연결된 주문으로 제품을 삭제하려고 할 때 외래 키 제약 조건 위반이 발생하지만 선택한 다른 제품 삭제가 롤백되는 방법을 확인합니다.

요약

일괄 삭제 인터페이스를 생성하려면, 확인란 열이 있는 GridView를 추가하고 버튼 웹 컨트롤을 추가하세요. 이를 클릭하면 선택한 모든 행이 단일 원자 작업으로 삭제됩니다. 이 자습서에서는 이전 두 자습서에서 수행한 작업을 함께 압정하여 이러한 인터페이스를 빌드했습니다. 즉, 확인란의 GridView 열을 추가하고트랜잭션 내에서 데이터베이스 수정 사항을 래핑합니다. 첫 번째 튜토리얼에서는 확인란 열이 있는 GridView를 만들었고, 다음 튜토리얼에서는 값의 List(Of T)ProductID로 전달할 때 트랜잭션 범위 내에서 모두 삭제하는 메서드를 BLL에서 구현했습니다.

다음 자습서에서는 일괄 처리 삽입을 수행하기 위한 인터페이스를 만듭니다.

행복한 프로그래밍!

작성자 정보

7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 연구해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 Sams Teach Yourself ASP.NET 2.0 in 24 Hours입니다. 그에게 mitchell@4GuysFromRolla.com으로 연락할 수 있습니다.

특별히 감사드립니다.

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 힐튼 기제나우와 테레사 머피였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 mitchell@4GuysFromRolla.com으로 메시지를 보내 주세요.