다음을 통해 공유


.NET Framework 애플리케이션의 데이터 세트에 있는 데이터 유효성 검사

비고

클래스 및 관련 클래스는 DataSet 2000년대 초반의 레거시 .NET Framework 기술로, 애플리케이션이 데이터베이스와 연결이 끊긴 동안 애플리케이션이 메모리의 데이터로 작업할 수 있도록 합니다. 이 기술은 사용자가 데이터를 수정하고 변경 내용을 데이터베이스에 다시 유지할 수 있도록 하는 앱에 특히 유용합니다. 데이터 세트는 입증된 성공적인 기술이지만 새 .NET 애플리케이션에 권장되는 방법은 Entity Framework Core를 사용하는 것입니다. Entity Framework는 테이블 형식 데이터를 개체 모델로 사용하는 보다 자연스러운 방법을 제공하며 더 간단한 프로그래밍 인터페이스를 제공합니다.

데이터 유효성 검사는 데이터 개체에 입력되는 값이 데이터 세트 스키마 내의 제약 조건을 준수하는지 확인하는 프로세스입니다. 또한 유효성 검사 프로세스는 이러한 값이 애플리케이션에 대해 설정된 규칙을 따르는지 확인합니다. 기본 데이터베이스에 업데이트를 보내기 전에 데이터의 유효성을 검사하는 것이 좋습니다. 이렇게 하면 애플리케이션과 데이터베이스 간의 잠재적 왕복 횟수뿐만 아니라 오류가 줄어듭니다.

데이터 세트 자체에 유효성 검사를 작성하여 데이터 세트에 기록되는 데이터가 유효한지 확인할 수 있습니다. 데이터 세트는 업데이트가 수행되는 방식(폼의 컨트롤, 구성 요소 내 또는 다른 방법으로 직접)에 관계없이 데이터를 확인할 수 있습니다. 데이터 세트는 데이터베이스 백 엔드와 달리 애플리케이션의 일부이므로 애플리케이션별 유효성 검사를 빌드하는 논리적 위치입니다.

애플리케이션에 유효성 검사를 추가하는 가장 좋은 위치는 데이터 세트의 부분 클래스 파일에 있습니다. Visual Basic 또는 Visual C#에서 데이터 세트 디자이너 를 열고 유효성 검사를 만들 열 또는 테이블을 두 번 클릭합니다. 이 작업을 통해 코드 파일을 열어 ColumnChanging 또는 RowChanging 이벤트 처리기를 만들 수 있습니다.

private static void OnColumnChanging(object sender, DataColumnChangeEventArgs e)
{

}

데이터의 유효성 검사

데이터 세트 내의 유효성 검사는 다음과 같은 방법으로 수행됩니다.

  • 변경 중에 개별 데이터 열의 값을 확인할 수 있는 고유한 애플리케이션별 유효성 검사를 만듭니다. 자세한 내용은 방법: 열 변경 중 데이터 유효성 검사

  • 전체 데이터 행이 변경되는 동안 데이터를 값으로 확인할 수 있는 고유한 애플리케이션별 유효성 검사를 만듭니다. 자세한 내용은 행 변경 시 데이터 검증 방법을 참조하세요.

  • 데이터 세트의 실제 스키마 정의의 일부로 키, 고유 제약 조건 등을 만듭니다.

  • 개체의 DataColumn 속성(예: MaxLength, AllowDBNullUnique)을 설정하여

DataTable 개체에 의해 레코드에서 변경이 발생할 때 여러 이벤트가 발생합니다.

  • ColumnChangingColumnChanged 이벤트는 각각의 열이 변경될 때와 변경 후에 발생합니다. 이 ColumnChanging 이벤트는 특정 열에서 변경 내용의 유효성을 검사하려는 경우에 유용합니다. 제안된 변경에 대한 정보는 이벤트에 인수로 전달됩니다.
  • RowChangingRowChanged 이벤트는 행이 변경되는 동안 및 이후에 발생합니다. 이 RowChanging 이벤트는 더 일반적입니다. 행의 어딘가에서 변경이 발생하지만 어떤 열이 변경되었는지 알 수 없음을 나타냅니다.

기본적으로 열에 대한 각 변경 내용은 4개의 이벤트를 발생합니다. 첫 번째 ColumnChanging 이벤트와 변경 중인 특정 열에 대한 ColumnChanged 이벤트입니다. 다음은 RowChangingRowChanged 이벤트입니다. 행을 여러 개 변경하는 경우 각 변경에 대해 이벤트가 발생합니다.

비고

데이터 행의 BeginEdit 메서드는 개별 열이 변경될 때마다 RowChangingRowChanged 이벤트를 해제합니다. 그 경우 메서드 EndEdit가 호출될 때까지 RowChangingRowChanged 이벤트가 단 한 번만 발생되므로 해당 이벤트는 발생하지 않습니다. 자세한 내용은 데이터 세트를 채우는 동안 제약 조건 해제를 참조하세요.

선택하는 이벤트는 유효성 검사를 얼마나 세분화할지에 따라 달라집니다. 열이 변경될 때 오류를 즉시 잡는 것이 중요한 경우, ColumnChanging 이벤트를 활용하여 유효성 검사를 구축합니다. 그렇지 않으면 RowChanging 이벤트를 사용하여 여러 오류를 한 번에 포착할 수 있습니다. 또한 한 열의 값이 다른 열의 내용에 따라 유효성을 검사할 수 있도록 데이터가 구조화된 경우 이벤트 중에 RowChanging 유효성 검사를 수행합니다.

개체의 DataTable 레코드가 업데이트되면 변경이 진행 중일 때와 완료된 후에 모두 응답할 수 있도록 개체가 이벤트를 발생시킵니다.

애플리케이션에서 형식화된 데이터 세트를 사용하는 경우 강력한 형식의 이벤트 처리기를 만들 수 있습니다. 그러면 처리기를 만들 수 있는 4개의 형식화된 이벤트가 추가됩니다. dataTableNameRowChangingdataTableNameRowChangeddataTableNameRowDeletingdataTableNameRowDeleted 이러한 형식화된 이벤트 처리기는 코드를 더 쉽게 작성하고 읽을 수 있도록 테이블의 열 이름을 포함하는 인수를 전달합니다.

데이터 업데이트 이벤트

이벤트 설명
ColumnChanging 열의 값이 변경되고 있습니다. 이 이벤트는 제안된 새 값과 함께 행과 열을 전달합니다.
ColumnChanged 열의 값이 변경되었습니다. 이 이벤트는 제안된 값과 함께 행과 열의 정보를 전달해 줍니다.
RowChanging 개체에 DataRow 적용된 변경 내용이 데이터 세트로 다시 커밋됩니다. 메서드 BeginEdit를 호출하지 않은 경우, ColumnChanging 이벤트가 발생한 직후 각 열 변경에 대해 RowChanging 이벤트가 발생합니다. BeginEdit을(를) 변경하기 전에 호출한 경우, RowChanging 메서드를 호출할 때만 EndEdit 이벤트가 발생합니다.

이 이벤트는 수행 중인 작업 유형(변경, 삽입 등)을 나타내는 값과 함께 행을 사용자에게 전달합니다.
RowChanged 행이 변경되었습니다. 이 이벤트는 수행 중인 작업 유형(변경, 삽입 등)을 나타내는 값과 함께 행을 사용자에게 전달합니다.
RowDeleting 행이 삭제되고 있습니다. 이 이벤트는 수행 중인 작업 유형(삭제)을 나타내는 값과 함께 행을 사용자에게 전달합니다.
RowDeleted 행이 삭제되었습니다. 이 이벤트는 수행 중인 작업 유형(삭제)을 나타내는 값과 함께 행을 사용자에게 전달합니다.

ColumnChanging, RowChangingRowDeleting 이벤트는 업데이트 프로세스 중에 발생합니다. 이러한 이벤트를 사용하여 데이터의 유효성을 검사하거나 다른 유형의 처리를 수행할 수 있습니다. 이러한 이벤트 중에 업데이트가 진행 중이므로 예외를 throw하여 업데이트가 완료되지 않도록 취소할 수 있습니다.

ColumnChangedRowChangedRowDeleted 이벤트는 업데이트가 성공적으로 완료되면 발생하는 알림 이벤트입니다. 이러한 이벤트는 성공적인 업데이트에 따라 추가 작업을 수행하려는 경우에 유용합니다.

열 변경 중 데이터 유효성 검사

비고

데이터 세트 디자이너는 유효성 검사 논리를 데이터 세트에 추가할 수 있는 부분 클래스를 만듭니다. 디자이너에서 생성된 데이터 세트는 partial 클래스의 코드를 삭제하거나 변경하지 않습니다.

데이터 열의 값이 변경되었을 때, ColumnChanging 이벤트에 응답하여 데이터의 유효성을 검사할 수 있습니다. 이 이벤트가 발생하면 현재 열에 대해 제안되는 값이 포함된 이벤트 인수(ProposedValue)를 전달합니다. e.ProposedValue의 내용에 따라 다음을 수행할 수 있습니다.

  • 아무 작업도 수행하지 않고 제안된 값을 수락합니다.

  • 열 변경 이벤트 처리기 내에서 열 오류(SetColumnError)를 설정하여 제안된 값을 거부합니다.

  • 필요에 따라 컨트롤을 ErrorProvider 사용하여 사용자에게 오류 메시지를 표시합니다. 자세한 내용은 ErrorProvider 구성 요소를 참조하세요.

이벤트 중에 RowChanging 유효성 검사를 수행할 수도 있습니다.

행을 변경하는 동안 데이터 유효성 검사

유효성을 검사하려는 각 열에 애플리케이션의 요구 사항을 충족하는 데이터가 포함되어 있는지 확인하는 코드를 작성할 수 있습니다. 제안된 값이 허용되지 않는 경우 오류가 있음을 나타내도록 열을 설정하여 이 작업을 수행합니다. 다음 예제에서는 열이 0 이하일 때 Quantity 열 오류를 설정합니다. 행 변경 이벤트 처리기는 다음 예제와 유사해야 합니다.

행이 변경되면 데이터의 유효성을 검사하려면(Visual Basic)

  1. 데이터 세트 디자이너에서 데이터 세트를 여세요. 자세한 내용은 연습: 데이터 세트 디자이너에서 데이터 세트 만들기를 참조하세요.

  2. 유효성을 검사할 테이블의 제목 표시줄을 두 번 클릭합니다. 이 작업은 데이터 세트의 DataTable 부분 클래스 파일에 있는 이벤트 처리기를 자동으로 만듭니다RowChanging.

    팁 (조언)

    테이블 이름 왼쪽을 두 번 클릭하여 행 변경 이벤트 처리기를 만듭니다. 테이블 이름을 두 번 클릭하면 편집할 수 있습니다.

    Private Sub Order_DetailsDataTable_Order_DetailsRowChanging(
        ByVal sender As System.Object, 
        ByVal e As Order_DetailsRowChangeEvent
      ) Handles Me.Order_DetailsRowChanging
    
        If CType(e.Row.Quantity, Short) <= 0 Then
            e.Row.SetColumnError("Quantity", "Quantity must be greater than 0")
        Else
            e.Row.SetColumnError("Quantity", "")
        End If
    End Sub
    

행이 변경되면 데이터의 유효성을 검사하려면(C#)

  1. 데이터 세트 디자이너에서 데이터 세트를 여세요. 자세한 내용은 연습: 데이터 세트 디자이너에서 데이터 세트 만들기를 참조하세요.

  2. 유효성을 검사할 테이블의 제목 표시줄을 두 번 클릭합니다. 이 작업은 에 대한 DataTable부분 클래스 파일을 만듭니다.

    비고

    데이터 세트 디자이너는 이벤트에 대한 RowChanging 이벤트 처리기를 자동으로 만들지 않습니다. 이벤트를 처리하는 RowChanging 메서드를 만들고 코드를 실행하여 테이블의 초기화 메서드에서 이벤트를 연결해야 합니다.

  3. partial 클래스에 다음 코드를 복사합니다.

    public override void EndInit()
    {
        base.EndInit();
        Order_DetailsRowChanging += TestRowChangeEvent;
    }
    
    public void TestRowChangeEvent(object sender, Order_DetailsRowChangeEvent e)
    {
        if ((short)e.Row.Quantity <= 0)
        {
            e.Row.SetColumnError("Quantity", "Quantity must be greater than 0");
        }
        else
        {
            e.Row.SetColumnError("Quantity", "");
        }
    }
    

변경된 행을 검색하려면

데이터 테이블의 각 행에는 RowState 열거형의 값을 사용하여 해당 행의 현재 상태를 추적하는 속성이 DataRowState 있습니다. 데이터 세트 또는 데이터 테이블에서 변경된 행을 반환하려면 DataSet 또는 DataTableGetChanges 메서드를 호출할 수 있습니다. 데이터 세트의 메서드를 호출하여 호출 GetChanges 하기 전에 변경 내용이 HasChanges 있는지 확인할 수 있습니다.

비고

메서드를 호출 AcceptChanges 하여 데이터 세트 또는 데이터 테이블에 변경 내용을 커밋한 후 메서드는 GetChanges 데이터를 반환하지 않습니다. 애플리케이션이 변경된 행을 처리해야 하는 경우 메서드를 호출 AcceptChanges 하기 전에 변경 내용을 처리해야 합니다.

GetChanges 데이터 세트 또는 데이터 테이블의 메서드를 호출하면 변경된 레코드만 포함된 새 데이터 세트 또는 데이터 테이블이 반환됩니다. 특정 레코드(예: 새 레코드 또는 수정된 레코드만)를 얻으려면 열거형의 DataRowState 값을 매개 변수로 메서드에 GetChanges 전달할 수 있습니다.

열거형을 DataRowVersion 사용하여 행의 다른 버전에 액세스합니다(예: 행을 처리하기 전에 행에 있던 원래 값).

데이터 세트에서 변경된 모든 레코드를 얻으려면

  • 데이터 세트의 GetChanges 메서드를 호출합니다.

    다음 예제에서는 호출 changedRecords 된 새 데이터 세트를 만들고 다른 dataSet1데이터 세트의 변경된 모든 레코드로 채웁니다.

    DataSet changedRecords = dataSet1.GetChanges();
    

데이터 테이블에서 변경된 모든 레코드를 얻으려면

  • GetChanges DataTable의 메서드를 호출합니다.

    다음 예제에서는 호출 changedRecordsTable 된 새 데이터 테이블을 만들고 다른 dataTable1데이터 테이블의 변경된 모든 레코드로 채웁니다.

    DataTable changedRecordsTable = dataTable1.GetChanges();
    

특정 행 상태가 있는 모든 레코드를 얻으려면

  • GetChanges 데이터 세트 또는 데이터 테이블의 메서드를 DataRowState 호출하고 열거형 값을 인수로 전달합니다.

    다음 예제에서는 호출 addedRecords 된 새 데이터 세트를 만들고 데이터 세트에 추가 dataSet1 된 레코드로만 채우는 방법을 보여 줍니다.

    DataSet addedRecords = dataSet1.GetChanges(DataRowState.Added);
    

    다음 예제에서는 테이블에 최근에 추가된 모든 레코드를 반환하는 Customers 방법을 보여줍니다.

    private NorthwindDataSet.CustomersDataTable GetNewRecords()
    {
        return (NorthwindDataSet.CustomersDataTable)
            northwindDataSet1.Customers.GetChanges(DataRowState.Added);
    }
    

원래 버전의 DataRow에 액세스

데이터 행이 변경되면 데이터 세트는 행의 원래(Original) 및 새(Current) 버전을 모두 유지합니다. 예를 들어 메서드를 AcceptChanges 호출하기 전에 애플리케이션은 열거형에 정의된 대로 다른 버전의 레코드에 DataRowVersion 액세스하고 그에 따라 변경 내용을 처리할 수 있습니다.

비고

행의 다른 버전은 편집된 후에 그리고 특정 메서드 AcceptChanges가 호출되기 전까지 만 존재합니다. 메서드가 AcceptChanges 호출된 후에는 현재 버전과 원래 버전이 동일합니다.

DataRowVersion 열 인덱스(또는 열 이름을 문자열로)와 함께 값을 전달하면 해당 열의 특정 행 버전에서 값이 반환됩니다. 변경된 열은 ColumnChangingColumnChanged 이벤트에서 식별됩니다. 유효성 검사를 위해 다른 행 버전을 검사하는 것이 좋습니다. 그러나 제약 조건을 일시적으로 일시 중단한 경우에는 해당 이벤트가 발생하지 않으며 변경된 열을 프로그래밍 방식으로 식별해야 합니다. 컬렉션을 반복하면서 다른 DataRowVersion 값을 비교하여 이 작업을 수행할 수 있습니다.

레코드의 원래 버전을 얻으려면

  • 반환하려는 행의 값을 전달 DataRowVersion 하여 열 값에 액세스합니다.

    다음 예제에서는 DataRowVersion 값을 사용하여 DataRowCompanyName 필드의 원래 값을 가져오는 방법을 보여줍니다.

    string originalCompanyName;
    originalCompanyName = northwindDataSet1.Customers[0]
        ["CompanyName", DataRowVersion.Original].ToString();
    

현재 버전의 DataRow에 액세스

레코드의 현재 버전을 얻으려면

  • 열 값에 액세스한 다음 반환하려는 행의 버전을 나타내는 매개 변수를 인덱스로 추가합니다.

    다음 예제에서는 DataRowCompanyName필드에서 현재 값을 가져오기 위해 DataRowVersion 값을 사용하는 방법을 보여줍니다.

    string currentCompanyName;
    currentCompanyName = northwindDataSet1.Customers[0]
        ["CompanyName", DataRowVersion.Current].ToString();