Icon Setting Master-Detail Links on Tables

A master-detail link is a property-based linkage between a master TDataSource component and a detail TEDBTable component. Once a master-detail link is established, any changes to the master TDataSource component will cause the detail TEDBTable component to automatically reflect the change and show only the detail rows that match the current master row based upon the link criteria. Master-detail links use ranges for their functionality, and therefore are dependent upon the active index in the detail table. Like ranges, master-detail links may be combined with expression filters set using the Filter and Filtered propertes and/or code-based filters set using the OnFilterRow event to further filter the rows in the detail table.

Defining the Link Properties
Setting master-detail links on tables is accomplished through four properties in the detail TEDBTable component. These properties are the MasterSource, MasterColumns, IndexName, and IndexFieldNames properties.

The first step in setting a master-detail link is to assign the MasterSource property. The MasterSource property refers to a TDataSource component. This makes master-detail links very flexible, because the TDataSource component can provide data from any TDataSet-descendant component such as a TEDBTable or TEDBQuery component as well as many other non-ElevateDB dataset components.

Information For the link to be valid, the TDataSource DataSet property must refer to a valid TDataSet-descendant component.

The next step is to assign the IndexName property, or IndexFieldNames property, so that the active index, and the columns that make up that index, will match the columns that you wish to use for the link. The only difference between specifying the IndexName property versus the IndexFieldNames property is that the IndexName property expects the name of an index, whereas the IndexFieldNames only expects the names of columns in the table that match the columns found in an index in the table from left-to-right. The IndexFieldNames property also does not require that all of the columns in an existing index be specified in order to match with that existing index, only enough to be able to select the index so that it will satisfy the needs of the master-detail link.

Finally, the MasterColumns property must be assigned a value. This property requires a column or list of columns separated by semicolons from the master data source that match the columns in the active index for the detail table.

To illustrate all of this we'll use an example. Let's suppose that we have two tables with the following structure and we wish to link them via a master-detail link:

Customer Table

Column #    Name              DataType     Size
----------------------------------------------
1          CustomerID        ftString     10
2          CustomerName      ftString     30
3          ContactName       ftString     30
4          Phone             ftString     10
5          Fax               ftString     10
6          EMail             ftString     30

Information Indexes in this case are not important since this will be the master table

Orders Table

Column #    Name              DataType     Size
----------------------------------------------
1          CustomerID        ftString     10
2          OrderNumber       ftString     10
3          OrderDate         ftDate       0
4          OrderAmount       ftBCD        2
   
Index Name      Columns In Index             Options
------------------------------------------------------
Primary_Key     CustomerID;OrderNumber      ixPrimary

We would use the following example code to establish a master-detail link between the two tables. In this example it is assumed that a TDataSource component called CustomerSource exists and points to a TEDBTable component for the "customer" table:

begin
   with OrdersTable do
      begin
      { Set to the natural order, which in this case
        is the primary key }
      IndexName:='';
      { Assign the MasterSource property }
      MasterSource:=CustomerSource;
      { Set the MasterColumns property to point to the
        CustomerID column from the Customer table }
      MasterColumns:='CustomerID';
      end;
end;

Now any time the current row in the CustomerSource data source changes in any way, the OrdersTable will automatically reflect that change and only show rows that match the master row's CustomerID column. Below is the same example, but changed to use the IndexFieldNames property instead:

begin
   with OrdersTable do
      begin
      { Set to the CustomerID column }
      IndexFieldNames:='CustomerID';
      { Assign the MasterSource property }
      MasterSource:=CustomerSource;
      { Set the MasterColumns property to point to the
        CustomerID column from the Customer table }
      MasterColumns:='CustomerID';
      end;
end;

Information Because a master-detail link uses data-event notification in the TDataSource component for maintaining the link, if the TDataSet component referred to by the TDataSource component's DataSet property calls its DisableControls method, it will not only disable the updating of any data-aware controls that refer to it, but it will also disable any master-detail links that refer to it also. This is the way the TDataSet and TDataSource components have been designed, so this is an expected behavior that you should keep in mind when designing your application.
Image