다음을 통해 공유


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

참고 항목

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

데이터 유효성 검사는 데이터 개체에 입력되는 값이 데이터 세트의 스키마 내 제약 조건을 따르는지 확인하는 프로세스입니다. 유효성 검사 프로세스에서는 이러한 값이 애플리케이션에 설정된 규칙을 따르는지 확인하는 작업도 수행됩니다. 기본 데이터베이스에 업데이트를 보내기 전에 데이터의 유효성을 검사하는 것이 좋습니다. 이렇게 하면 애플리케이션과 데이터베이스 사이에서 발생할 수 있는 잠재적 라운드트립 횟수를 줄일 수 있습니다.

데이터 세트 자체에서 유효성 검사를 빌드하면 데이터 세트에 기록 중인 데이터가 유효한지 확인할 수 있습니다. 데이터 세트는 업데이트 방식(폼의 컨트롤에서 바로 업데이트, 구성 요소에서 업데이트 등)에 관계없이 데이터를 확인할 수 있습니다. 데이터 세트는 (데이터베이스 백 엔드와는 달리) 애플리케이션의 일부이므로, 애플리케이션별 유효성 검사를 빌드하는 논리적 장소이기도 합니다.

애플리케이션에 유효성 검사를 추가하기에 가장 좋은 장소는 데이터 세트의 partial 클래스 파일입니다. Visual Basic 또는 Visual C#에서 데이터 세트 디자이너를 열고, 유효성 검사를 만들 열이나 테이블을 두 번 클릭합니다. 그러면 ColumnChanging 또는 RowChanging 이벤트 처리기를 만들 수 있는 코드 파일이 열립니다.

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

}

데이터의 유효성 검사

데이터 세트에서의 유효성 검사는 다음 방법으로 수행합니다.

레코드에서 변경이 발생할 때 DataTable 개체는 다양한 이벤트를 유발합니다.

  • ColumnChangingColumnChanged 이벤트는 개별 열을 변경하는 동안과 변경한 후에 발생합니다. ColumnChanging 이벤트는 특정 열 변경 내용의 유효성을 검사할 때 유용합니다. 제안된 변경에 대한 정보는 이벤트와 함께 인수로서 전달됩니다.
  • RowChangingRowChanged 이벤트는 행을 변경하는 동안과 변경한 후에 발생합니다. RowChanging 이벤트는 더 일반적입니다. 이 이벤트는 행의 특정 부분이 변경되고 있음을 나타내지만, 변경된 열을 알 수는 없습니다.

열을 변경하면 기본적으로 이벤트가 4개가 발생합니다. 첫 번째 이벤트는 변경 중인 특정 열에 대한 ColumnChangingColumnChanged 이벤트입니다. 다음은 RowChangingRowChanged 이벤트입니다. 행에서 여러 변경이 적용 중이라면, 이벤트는 각 변경에 대해 발생합니다.

참고 항목

데이터 행의 BeginEdit 메서드는 개별 열이 변경될 때마다 RowChangingRowChanged 이벤트를 해제합니다. 이 경우 이벤트는 RowChangingRowChanged 이벤트가 한 번만 발생하여 EndEdit 메서드가 호출된 후에만 발생합니다. 자세한 내용은 데이터 세트를 채우는 동안 제약 조건 해제를 참조하세요.

사용자가 선택하는 이벤트는 유효성 검사의 세분화 수준에 따라 달라집니다. 열이 변경될 때 오류를 즉시 포착해야 한다면, ColumnChanging 이벤트를 사용하여 유효성 검사를 빌드해야 합니다. 그렇지 않다면 RowChanging 이벤트를 사용하여 한 번에 여러 오류를 포착합니다. 또한 특정 열 값의 유효성을 다른 열의 내용을 바탕으로 검사하도록 데이터가 구성되어 있다면, RowChanging 이벤트 중에 유효성 검사를 수행해야 합니다.

레코드가 업데이트되면 DataTable 개체는 사용자가 변경 발생 중이나 변경 이후에 응답할 수 있는 이벤트를 유발합니다.

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

데이터 업데이트 이벤트

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

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

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

ColumnChanged, RowChanged, RowDeleted 이벤트는 업데이트가 성공적으로 완료될 때 발생하는 알림 이벤트입니다. 이러한 이벤트는 성공적인 업데이트를 바탕으로 추가 작업을 수행할 때 유용합니다.

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

참고 항목

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

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

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

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

  • 필요하다면 ErrorProvider 컨트롤을 사용하여 사용자에게 오류 메시지를 표시할 수도 있습니다. 자세한 내용은 ErrorProvider 구성 요소를 참조하세요.

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

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

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

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

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

  2. 유효성을 검사할 테이블의 제목 표시줄을 두 번 클릭합니다. 이 작업을 수행하면 데이터 세트의 partial 클래스 파일에 있는 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용 partial 클래스 파일을 만듭니다.

    참고 항목

    데이터 세트 디자이너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", "");
        }
    }
    

변경된 행을 검색하려면

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

참고 항목

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

데이터 세트 또는 데이터 테이블의 GetChanges 메서드를 호출하면 변경된 레코드만 포함하는 새 데이터 세트나 데이터 테이블이 반환됩니다. 특정 레코드를 가져오고 싶다면(예를 들어 새 레코드 또는 수정된 레코드만 가져오고 싶다면) DataRowState 열거형의 값을 GetChanges 메서드에 매개 변수로서 전달하면 됩니다.

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

데이터 세트에서 변경된 모든 레코드를 가져오려면

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

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

    DataSet changedRecords = dataSet1.GetChanges();
    

데이터 테이블에서 변경된 모든 레코드를 가져오려면

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

    다음 예제에서는 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 이벤트 중에 식별됩니다. 이때 유효성 검사를 위해 다른 행 버전을 검사할 수 있습니다. 그러나 제약 조건을 일시적으로 중단했다면 이러한 이벤트는 발생하지 않으며, 변경된 열을 프로그래밍 방식으로 식별해야 합니다. 이렇게 하려면 Columns 컬렉션을 반복하고 다양한 DataRowVersion 값을 비교해야 합니다.

레코드의 원래 버전을 가져오려면

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

    다음 예제에서는 DataRowVersion 값을 사용하여 DataRow에서 CompanyName 필드의 원래 값을 가져오는 방법을 확인할 수 있습니다.

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

DataRow의 현재 버전에 액세스

레코드의 현재 버전을 가져오려면

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

    다음 예제에서는 DataRowVersion 값을 사용하여 DataRow에서 CompanyName 필드의 현재 값을 가져오는 방법을 확인할 수 있습니다.

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