다음을 통해 공유


.NET Framework 개발의 계층적 업데이트

참고 항목

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

“계층적 업데이트”는 참조 무결성 규칙을 유지하면서 두 개 이상의 관련 테이블이 있는 데이터 세트에서 업데이트된 데이터를 데이터베이스에 다시 저장하는 프로세스를 의미합니다. “참조 무결성”은 관련 레코드 삽입, 업데이트 및 삭제 동작을 제어하는 데이터베이스의 제약 조건에서 제공하는 일관성 규칙을 말합니다. 예를 들어 참조 무결성은 고객 레코드 만들기를 적용한 후 고객에 대한 주문을 만들도록 허용합니다. 데이터 세트의 관계에 대한 자세한 내용은 데이터 세트의 관계를 참조하세요.

계층적 업데이트 기능은 TableAdapterManager를 사용하여 형식화된 데이터 세트에서 TableAdapter를 관리합니다. TableAdapterManager 구성 요소는 .NET 형식이 아닌 Visual Studio에서 생성된 클래스입니다. 데이터 원본 창에서 Windows Form 또는 WPF Visual Studio 페이지로 테이블을 끌면 TableAdapterManager 형식의 변수가 폼 또는 페이지에 추가되고 디자이너의 구성 요소 트레이에 표시됩니다. TableAdapterManager 클래스에 대한 자세한 내용은 TableAdapter의 TableAdapterManager 참조 섹션을 참조하세요.

기본적으로 데이터 세트는 관련 테이블을 "관계 전용"으로 처리합니다. 즉, 외래 키 제약 조건을 적용하지 않습니다. 데이터 세트 디자이너를 사용하여 디자인 타임에 해당 설정을 수정할 수 있습니다. 두 테이블 간의 관계 선을 선택하여 관계 대화 상자를 표시합니다. 여기에서 수정한 내용에 따라 관련 테이블의 변경 내용을 데이터베이스에 다시 보낼 때 TableAdapterManager가 동작하는 방식이 결정됩니다.

데이터 세트에서 계층적 업데이트를 사용하도록 설정

기본적으로 계층적 업데이트는 프로젝트에서 추가되거나 만들어진 모든 새 데이터 세트에 대해 사용하도록 설정됩니다. 데이터 세트에서 형식화된 데이터 세트의 계층적 업데이트 속성을 True 또는 False로 설정하여 계층적 업데이트를 설정하거나 해제합니다.

계층적 업데이트 설정

테이블 간에 새 관계 만들기

두 테이블 간에 새 관계를 만들려면 데이터 세트 디자이너에서 각 테이블의 제목 표시줄을 선택하고 마우스 오른쪽 단추를 클릭한 다음 관계 추가를 선택합니다.

계층 구조 업데이트 관계 추가 메뉴

외래 키 제약 조건, 연계 업데이트 및 삭제 이해

생성된 데이터 세트 코드에서 데이터베이스의 외래 키 제약 조건 및 연계 동작이 만들어지는 방법을 이해하는 것이 중요합니다.

기본적으로 데이터 세트의 데이터 테이블은 데이터베이스의 관계와 일치하는 관계(DataRelation)를 사용하여 생성됩니다. 그러나 데이터 세트의 관계는 외래 키 제약 조건으로 생성되지 않습니다. DataRelationUpdateRule 또는 DeleteRule이 적용되지 않는 관계 전용으로 구성됩니다.

기본적으로 연속 업데이트 또는 하위 삭제가 설정된 상태에서 데이터베이스 관계가 설정된 경우에도 연속 업데이트 및 하위 삭제는 해제됩니다. 예를 들어 새 고객과 새 주문을 만든 다음 데이터를 저장하려고 하면 데이터베이스에 정의된 외래 키 제약 조건과 충돌이 발생할 수 있습니다. 자세한 내용은 데이터 세트를 채우는 동안 제약 조건 해제를 참조하세요.

업데이트를 수행하는 순서 설정

업데이트를 수행하는 순서를 설정하면 데이터 세트의 모든 테이블에 수정된 모든 데이터를 저장하는 데 필요한 개별 삽입, 업데이트 및 삭제 순서가 설정됩니다. 계층적 업데이트를 사용하는 경우 먼저 삽입이 수행되고 업데이트가 삭제된 다음 삭제가 수행됩니다. TableAdapterManager는 먼저 업데이트를 수행하고 삽입을 수행한 다음 삭제를 수행하도록 설정할 수 있는 UpdateOrder 속성을 제공합니다.

참고 항목

업데이트 순서는 모두 포함한다는 것을 이해하는 것이 중요합니다. 즉, 업데이트를 수행하는 경우 데이터 세트의 모든 테이블에 대한 삽입 및 삭제 작업이 수행됩니다.

UpdateOrder 속성을 설정하려면 데이터 원본 창에서 폼으로 항목을 끌어오고 구성 요소 트레이에서 TableAdapterManager를 선택한 다음 속성 창에서 UpdateOrder 속성을 설정합니다.

계층적 업데이트를 수행하기 전에 데이터 세트 백업 복사본 만들기

TableAdapterManager.UpdateAll() 메서드를 호출하여 데이터를 저장하면 TableAdapterManager가 단일 트랜잭션으로 각 테이블의 데이터를 업데이트하려고 시도합니다. 테이블 업데이트가 일부라도 실패하면 전체 트랜잭션이 롤백됩니다. 대부분의 경우 롤백은 애플리케이션을 원래 상태로 되돌립니다.

그러나 경우에 따라 백업 복사본에서 데이터 세트를 복원하는 것이 좋습니다. 한 가지 예는 자동 증분 값을 사용하는 경우가 될 수 있습니다. 예를 들어 저장 작업에 성공하지 못하면 자동 증분 값이 데이터 세트에서 다시 설정되지 않으며 데이터 세트는 자동 증분 값을 계속 만듭니다. 이로 인해 애플리케이션에서 허용되지 않을 수 있는 번호 매기기 간격이 남습니다. 이 문제가 발생하는 상황에서는 TableAdapterManager가 트랜잭션이 실패할 경우 기존 데이터 세트를 백업 복사본으로 대체하는 BackupDataSetBeforeUpdate 속성을 제공합니다.

참고 항목

백업 복사본이 TableAdapterManager.UpdateAll 메서드를 실행하는 동안에만 메모리에 유지됩니다. 따라서 이 백업 데이터 세트는 TableAdapterManager.UpdateAll 메서드가 실행을 완료하는 즉시 원래 데이터 세트를 대체하거나 범위를 벗어나기 때문에 이 백업 데이터 세트에 프로그래밍 방식으로 액세스할 수는 없습니다.

계층적 업데이트를 수행하도록 생성된 저장 코드 수정

TableAdapterManager.UpdateAll 메서드를 호출한 다음 관련 테이블이 포함된 데이터 세트의 이름을 전달하여 데이터 세트의 관련 데이터 테이블에서 데이터베이스로 변경 내용을 저장합니다. 예를 들어 NorthwindDataset에 포함된 모든 테이블의 업데이트를 백 엔드 데이터베이스로 보내려면 TableAdapterManager.UpdateAll(NorthwindDataset) 메서드를 실행합니다.

데이터 원본 창에서 항목을 놓으면 코드가 Form_Load 이벤트에 자동으로 추가되어 각 테이블을 채웁니다(TableAdapter.Fill 메서드). 또한 데이터 세트의 데이터를 데이터베이스에 다시 저장할 수 있도록 BindingNavigator저장 단추 클릭 이벤트에도 코드가 추가됩니다(TableAdapterManager.UpdateAll 메서드).

생성된 저장 코드에는 CustomersBindingSource.EndEdit 메서드를 호출하는 코드 줄도 포함됩니다. 구체적으로 이 코드는 폼에 추가된 첫 번째 BindingSourceEndEdit 메서드를 호출합니다. 다시 말해서 이 코드는 데이터 원본 창에서 폼으로 끈 첫 번째 테이블에 대해서만 생성됩니다. EndEdit 호출에서는 현재 편집 중인 데이터 바인딩된 컨트롤의 프로세스에 포함된 모든 변경 내용을 커밋합니다. 따라서 데이터 바인딩된 컨트롤에 계속 포커스가 있는 상태에서 저장 단추를 클릭하면 실제 저장 전에 해당 컨트롤에서 보류 중인 모든 편집 내용이 커밋됩니다(TableAdapterManager.UpdateAll 메서드).

참고 항목

데이터 세트 디자이너는 폼에 놓은 첫 번째 테이블에 대해서만 BindingSource.EndEdit 코드를 추가합니다. 그러므로 폼의 각 관련 테이블에 대해 BindingSource.EndEdit 메서드를 호출하는 코드 줄을 추가해야 합니다. 이 연습에서는 OrdersBindingSource.EndEdit 메서드 호출을 추가해야 합니다.

  1. BindingNavigator에서 저장 단추를 두 번 클릭하여 코드 편집기에서 Form1을 엽니다.

  2. OrdersBindingSource.EndEdit 메서드를 호출하는 줄 뒤에 CustomersBindingSource.EndEdit 메서드를 호출하는 코드 줄을 추가합니다. 저장 단추 클릭 이벤트 내의 코드는 다음과 같습니다.

    this.Validate();
    this.customersBindingSource.EndEdit();
    this.ordersBindingSource.EndEdit();
    this.tableAdapterManager.UpdateAll(this.northwindDataSet);
    

이처럼 데이터를 데이터베이스에 저장하기 전에 관련 자식 테이블에 대해 변경 내용을 커밋해야 할 뿐 아니라 새 자식 레코드를 데이터 세트에 추가하기 전에 새로 만든 부모 레코드도 커밋해야 할 수 있습니다. 다시 말해서 외래 키 제약 조건으로 인해 새 자식 레코드(Orders)를 데이터 세트에 추가할 수 있도록 설정되기 전에 새 부모 레코드(Customer)를 데이터 세트에 추가해야 할 수 있습니다. 자식 BindingSource.AddingNew 이벤트를 사용하면 이 작업을 수행할 수 있습니다.

참고 항목

새 부모 레코드를 커밋해야 하는지 여부는 데이터 원본에 바인딩하는 데 사용되는 컨트롤의 유형에 따라 결정됩니다. 이 연습에서는 개별 컨트롤을 사용하여 부모 테이블에 바인딩합니다. 이를 위해 새 부모 레코드를 커밋하는 추가 코드가 필요합니다. 대신 DataGridView 같은 복잡한 바인딩 컨트롤에 부모 레코드가 표시된 경우에는 이와 같이 부모 레코드에 대해 EndEdit 호출을 추가로 수행할 필요가 없습니다. 컨트롤의 기본 데이터 바인딩 기능이 새 레코드 커밋을 처리하기 때문입니다.

새 자식 레코드를 추가하기 전에 데이터 세트에서 부모 레코드를 커밋하는 코드를 추가하려면

  1. OrdersBindingSource.AddingNew 이벤트에 대한 이벤트 처리기를 만듭니다.

    • 디자인 뷰에서 Form1을 열고 구성 요소 트레이에서 OrdersBindingSource를 선택하고, 속성 창에서 이벤트를 선택한 다음 AddingNew 이벤트를 두 번 클릭합니다.
  2. CustomersBindingSource.EndEdit 메서드를 호출하는 코드 줄을 이벤트 처리기에 추가합니다. OrdersBindingSource_AddingNew 이벤트 처리기의 코드는 다음과 같습니다.

    this.customersBindingSource.EndEdit();
    

TableAdapterManager 참조

기본적으로 TableAdapterManager 클래스는 관련 테이블을 포함하는 데이터 세트를 만들 때 생성됩니다. 이 클래스가 생성되지 않도록 하려면 데이터 세트의 Hierarchical Update 속성 값을 false로 변경합니다. 관계가 있는 테이블을 Windows Form 또는 WPF 페이지의 디자인 화면으로 끌면 Visual Studio가 클래스의 멤버 변수를 선언합니다. 데이터 바인딩을 사용하지 않는 경우 변수를 수동으로 선언해야 합니다.

TableAdapterManager 클래스는 .NET 형식이 아닙니다. 따라서 설명서에서 조회할 수 없습니다. 이 클래스는 디자인 타임에 데이터 세트 생성 프로세스의 일부로 만들어집니다.

다음은 TableAdapterManager 클래스의 자주 사용되는 메서드 및 속성입니다.

멤버 설명
UpdateAll 메서드 모든 데이터 테이블의 모든 데이터를 저장합니다.
BackUpDataSetBeforeUpdate 속성 TableAdapterManager.UpdateAll method.Boolean.를 실행하기 전에 데이터 세트의 백업 복사본을 만들지 여부를 결정합니다.
tableName TableAdapter 속성 TableAdapter를 나타냅니다. 생성된 TableAdapterManager에는 관리하는 각 TableAdapter에 대한 속성이 포함됩니다. 예를 들어 Customers 및 Orders 테이블이 있는 데이터 세트는 CustomersTableAdapterOrdersTableAdapter 속성을 포함하는 TableAdapterManager를 통해 생성됩니다.
UpdateOrder 속성 개별 insert, update 및 delete 명령의 순서를 제어합니다. 이를 TableAdapterManager.UpdateOrderOption 열거형의 값 중 하나로 설정합니다.

기본적으로 UpdateOrderInsertUpdateDelete로 설정됩니다. 즉, 데이터 세트의 모든 테이블에 대해 삽입, 업데이트, 삭제 작업이 순서대로 수행됩니다.