Jump to content
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr ×
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr

[DocWiki 번역] 마스터-디테일 관계 (M/D)


Recommended Posts

Docwiki에 있는 "Master-Detail Relationship (M/D)"를 번역한 글: 번역일: 2022년 3월 29일)

위로 가기: Working with DataSets (FireDAC)

FireDAC에서는 유연한 방식으로 데이터셋을 마스터-디테일 관계로 구성할 수 있다.

목차


1 일반 (General)

마스터-디테일 관계를 이용하면 마스터 데이터셋의 현재 레코드를 기준으로 하여 자동으로 해당 디테일 데이터셋을 필터링할 수 있다. 예를 들어, 마스터 데이터셋에 "주문" 레코드가 있고, 해당 디테일 데이터셋에 "주문 항목" 레코드가 있을 때, 디테일 데이터셋에는 오직 현재 주문에 해당하는 주문 항목만 나타난다.

마스터 데이터셋에 특별히 설정할 것은 없다.

FireDAC에서 마스터-디테일 관계에 있는 디테일 데이터셋을 설정하는 수단은 기본적으로 2가지이다.

  • 파라미터-기반: 마스터 데이터셋 필드 값을 해당 디테일 TFDQuery 또는 TFDStoredProc의 파라미터에 할당한다. 그리고 나서 해당 디테일 데이터셋 쿼리는 다시 실행(#[DocWiki 번역] 명령(command) 실행하기 (FireDAC))된다.
  • 범위-기반: 마스터 데이터셋 필드 값을 사용하여 해당 디테일 데이터셋에서 "범위를 적용(#레코드 필터링하기)"한다. "현재 활성화된 인덱스(current active index)(#레코드 정렬하기)"가 있는 FireDAC 데이터셋이면 무엇이든 이 범위-기반 디테일 데이터셋이 될 수 있다.

이 두 수단을 결합하여 사용할 수도 있다. 둘 중 무엇을 선택할 지는 아래 표를 고려한다.

기능 파라미터-기반 범위-기반
디테일 쿼리가 반환하는 레코드 숫자에 제한이 있는 경우 +  
디테일 레코드가 신선한 경우 +  
마스터 변경 시, DBMS 작업과 트래픽 부담을 줄이려는 경우   +
마스터 변경 업데이트가 캐시(cache)에 보존되어 있는 경우   +
오프라인 모드에서 작업하는 경우   +
중앙집중식 캐시된 업데이트(Centralized Cached Updates)와 전파(propagation)를 지원하는 경우   +

FireDAC에서 마스터-디테일 관계의 데이터셋에 대해 적용할 수 있는 캐시된 업데이트(Cached Updates) 모드는 2가지가 있다.

  • 분산형 캐시된 업데이트 모드: 각 데이터셋 별로 독립적으로 변경을 추적한다. 고전적 방식이며, 기본 모드이다.
  • 중앙 집중식 캐시된 업데이트 모드: 마스터-디테일 관계인 여러 데이터셋들이 변경 로그 하나를 공유한다. 마스터 데이터셋의 변경을 해당 디테일 데이터셋으로 발생 순서대로 전파할 수 있다. 여기에는 자동-증가 필드의 값도 해당된다.

 

2 파라미터-기반 마스터/디테일 (Parameters-based M/D)

파라미터-기반 마스터-디테일(M/D) 관계를 설정하려면, 다음과 같이 단계를 수행한다.

  1. TFDQuery (또는 기타 FireDAC 데이터셋)를 폼에 올려 놓는다.
  2. 올려둔 데이터셋의 이름을 qOrders라고 지정한다. 이것이 마스터 데이터셋이다.
  3. 아래 SQL을 할당하여 설정한다.
    SELECT * FROM {id Orders}
  4. TDataSource를 폼에 올려 놓는다. 이름을 dsOrders라고 지정한다. dsOrdersDataSet 프로퍼티를 qOrders로 지정한다.
  5. TFDQuery를 폼에 올려 놓는다. 이름을 qOrderDetails라고 지정한다. 이것이 디테일 데이터셋이다.
  6. 아래 SQL을 할당하여 설정한다.
    SELECT * FROM {id Order Details} WHERE OrderID = :OrderID
  7. 이 디테일 데이터셋의 MasterSource 프로퍼티를 dsOrders로 지정한다. 기본 설정이 끝났다.

어떻게 작동하는 걸까? FireDAC은 qOrderDetails 데이터셋을 위해 목록을 하나 구축하는데, 이 목록에는 qOrderDetails의 파라미터(들)과 여기에 해당하는 qOrders의 필드 값(들)을 한 쌍으로 만들고 이 쌍들을 모아놓는다. 한쌍을 구성하는 요소, 즉 짝이 되는 기준은 다음과 같다.

  • MasterFields 프로퍼티에 목록이 명시되지 않은 경우: 마스터와 디테일 데이터셋에서 이름이 같은 필드끼리 한쌍이 된다.
  • 그 외의 경우: MasterFields 프로퍼티 안에 필드들 목록이 있고, Params 컬렉션 안에는 파라미터들 목록이 있다. 이 각 목록에서 같은 위치에 있는 것끼리 짝이 된다. 

qOrders에서 현재 위치가 다른 레코드로 이동하면, FireDAC은 이동한 레코드의 필드 값을 파라미터에 할당한다. 위 경우에는 qOrderDetails :OrderID 파라미터에 qOrder 데이터셋의 OrderID 필드 값이 들어간다. 그리고 나서 qOrders가 다시 실행된다.

주의: 디테일 데이터셋의 BeforeOpenAfterOpen 이벤트는 발생하지 않는다. 그대신 OnMasterSetValue 이벤트를 사용하라.

 

3 범위-기반 마스터/디테일 (Range-based M/D)

범위-기반 마스터-디테일(M/D) 관계를 설정하려면, 다음과 같이 단계를 수행한다.

  1. TFDQuery (또는 기타 FireDAC 데이터셋)를 폼에 올려 놓는다.
  2. 올려둔 데이터셋의 이름을 qOrders라고 지정한다. 이것이 마스터 데이터셋이다.
  3. 아래 SQL을 할당하여 설정한다.
    SELECT * FROM {id Orders}
  4. TDataSource를 폼에 올려 놓는다. 이름을 dsOrders라고 지정한다. dsOrdersDataSet 프로퍼티를 qOrders로 지정한다.
  5. TFDQuery를 폼에 올려 놓는다. 이름을 qOrderDetails라고 지정한다. 이것이 디테일 데이터셋이다.
  6. 아래 SQL을 할당하여 설정한다.
    SELECT * FROM {id Order Details}
  7. 이 디테일 데이터셋의 MasterFields 프로퍼티를  ORDERID(마스터 데이터셋에 있는 ORDERID 필드)로 지정한다. 그리고 나서 IndexFieldNamesORDERID(디테일 데이터셋에 있는 ORDERID 필드)로 지정한다. 그리고 나서 MasterSource 프로퍼티를 dsOrders로 지정한다. 기본 설정이 끝났다.

어떻게 작동하는 걸까? FireDAC은 qOrderDetails 데이터셋을 위해 목록을 하나 구축하는데, 이 목록에는 qOrders의 필드와 qOrderDetails의 필드가 한쌍이 된다. 짝이 되는 기준은 MasterFields 프로퍼티에 있는 마스터 필드 목록과, IndexFieldNames 프로퍼티에 있는 디테일 필드 목록에서 순서 상 같은 위치에 있는 필드끼리 짝이 된다.

qOrders에서 현재 위치가 다른 레코드로 이동하면, FireDAC은 qOrderDetails에 해당 범위를 적용한다. 즉, "디테일 데이터셋의 필드와 마스터 데이터셋의 해당 필드는 값이 같다"라는 범위 조건이 적용된다. 위 경우에는 qOrderDetails OrderID 필드와 qOrder OrderID 필드가 같다는 조건이 적용된다.

 

4 방식들을 결합하기 (Combining Methods)

이 두가지 방식을 함께 사용하려면, 애플리케이션에서 파라미터-기반 설정과 범위-기반 설정을 모두 사용해야 하며, fiDetailsFetchOptions.Cache 옵션 안에 포함시켜야 한다. FireDAC은 먼저 범위-기반 M/D를 사용한다. 만약 데이터셋이 비어 있으면, 파라미터-기반 M/D를 사용한다. 새로 쿼리된 레코드는 FireDAC 내부 레코드 저장소에 추가된다.

또한 TFDDataSet.OnMasterSetValues 이벤트 핸들러를 사용하면, M/D 행위를 덮어쓰기(override)할 수 있다.

 

5 디테일 데이터셋 편집하기 (Editing Detail Datasets)

디테일 데이터셋에 새 레코드가 삽입되면, 마스터-디테일 관계에 참여하고 있는 필드에는 자동으로 해당 마스터 데이터셋 필드의 값이 채워진다. 디테일 데이터셋 필드 목록은 다음과 같이 정의된다.

  • 파라미터-기반 마스터-디테일(M/D): DetailFields 프로퍼티에 명시된 필드 목록(만약 없으면, 해당 파라미터와 이름이 같은 필드)
  • 범위-기반 마스터-디테일(M/D): IndexFieldNames에 명시된 필드 목록

디테일 레코드를 삽입하려면, 마스터 데이터셋의 상태는  반드시 브라우징(dsBrowse) 이어야 한다. 마스터 데이터셋과 디테일 데이터셋을 모두 삽입(dsInsert) 상태 또는 편집(dsEdit) 상태로 두는 것은 불가능하다.

마스터 데이터셋과 디테일 데이터셋이 캐시된 업데이트 모드인 경우, 애플리케이션에서 중앙집중식 캐시된 업데이트(Centralized Cached Updates)와 전파(propagation)를 활성화하려면, TFDSchemaAdapter를 사용한다. 그러기 위해서는 마스터 데이터셋과 디테일 데이터셋의 SchemaAdapter 프로퍼티는 반드시 동일한 TFDSchemaAdapter를 가리키고 있어야 하며, 디테일 데이터셋의  FetchOptions.DetailCascadeTrue이어야 한다.

 

6 마스터/디테일 안에서 이동하기 (Navigating in M/D)

애플리케이션에서 마스터 데이터셋 안을 이동(navigate)하면, 마스터 데이터셋의 현재 레코드가 달라질 때 마다 디테일 데이터셋이 새로고침 된다. 이 절차는 리소스를 소비하고 이동이 느려질 수 있다. 임시로 M/D 동기화를 비활성화하려면, 마스터 데이터셋에서 DisableControls / EnableControls를 호출한다.

qOrders.DisableControls;
try
  qOrders.First;
  while not qOrders.Eof do begin
    .....
    qOrders.Next;
  end;
finally
  qOrders.EnableControls;
end;

M/D 동기화가 비활성화일 때 동기화를 강제하려면, 마스터 데이터셋에서 ApplyMaster 메소드를 호출한다. 특정 디테일 데이터셋에서 임시로 M/D 동기화를 비활성화하려면, 해당 디테일 데이터셋의 MasterLink 프로퍼티의 DisableScroll / EnableScroll 메소드를 사용한다.

qOrderDetails.MasterLink.DisableScroll;
try
  qOrders.First;
  while not qOrders.Eof do begin
    if qOrders.FieldByName('OrderID').AsInteger = 100 then begin
      qOrderDetails.ApplyMaster;
      // qOrderDetails 데이터셋을 읽는다 - qOrders와 동기화된다.
    end;
    qOrders.Next;
  end;
finally
  qOrderDetails.MasterLink.EnableScroll;
end;

GUI 애플리케이션에서는 지연된 M/D 동기화가 유용할 수 있다. 그러면, 사용자가 그리드에서 스크롤을 할 때, 디테일 데이터셋이 즉시 새로고침되지 않고, 약간 지연하고 있다가 스크롤이 끝나서 더이상 이동이 없을 때 새로고침된다. 지연된 동기화(delayed synchronization)를 사용하려면, 디테일 데이터셋에서 FetchOptions.DetailDelay 프로퍼티에 값을 지정한다. 특정 디테일 데이터셋에서 임시로 "지연된 M/D 동기화"를 비활성화하고 즉시 동기화를 하려면, 해당 디테일 데이터셋의 MasterLink 프로퍼티의 DisableDelayedScroll  / EnableDelayedScroll 메소드를 사용한다.

기본값에서는, 상태 변경, 키가 아닌 필드 값 변경, 마스터 데이터셋 새로고침이 발생해도 디테일 데이터셋은 새로고침되지 않는다. 이렇게 해놓으면 디테일 데이터셋을 불필요하게 새로고침하지 않는다. 만약 당신의 애플리케이션에서 디테일 데이터셋이 항상 새로고침되도록 하려면, FetchOptions.DetailOptimizeFalse로 지정한다.

 

7 기타 자료 (See Also)

 

7.1 예제(Samples)

이 댓글 링크
다른 사이트에 공유하기

이 토의에 참여하세요

지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.

Guest
이 토픽(기고/질문)에 답하기

×   서식있는 텍스트로 붙여넣기.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   이전에 작성한 콘텐츠가 복원되었습니다..   편집창 비우기

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

중요한 정보

이용약관 개인정보보호정책 이용규칙 이 사이트가 더 잘 작동하기 위해 방문자의 컴퓨터에 쿠키가 배치됩니다. 쿠키 설정 변경에서 원하는 설정을 할 수 있습니다. 변경하지 않으면 쿠키를 허용하는 것으로 이해합니다.