Show/Hide Toolbars

TMS Aurelius Documentation

Navigation: Data Binding - TAureliusDataset > Using Fields

Dataset Fields (Many-Valued Associations)

Scroll Prev Top Next More

Dataset fields represent collections in a container object. In other words, dataset fields represent many-valued associations in the object. Consider the following class:

 

TInvoice = class

// <snip>

public

  property Id: Integer read FId write FId;

  property Items: TList<TInvoiceItem> read GetItems;

end;

 

The field "Items" is expected to be a TDatasetField, and represents all objects (records) in the Items collection. Different from entity fields, you don't access a reference to the list itself, using the dataset field.

 

In short, you can use the TDatasetField to build master-detail relationships. You can have, for example, a TDBGrid linked to a dataset representing a list of TInvoice objects, and a second TDBGrid linked to a dataset representing a list of TInvoiceItem objects. To link the second dataset (invoice items) to the first (invoices) you just need to set the DatasetField property of the second dataset. This will link the detail dataset to the collection of items in the first dataset. You can do it at runtime or design-time.

 

The following code snippet illustrates better how to link two datasets using the dataset field. It's worth to note that these dataset fields work as a regular TDatasetField. For a better understanding of how a TDatasetField works, please refer to Delphi documentation.

 

InvoiceDataset.SetSourceList(List);

InvoiceDataset.Manager := Manager1;

InvoiceDataset.Open;

ItemsDataset.DatasetField := InvoiceDataset.FieldByName('Items'as TDatasetField;

ItemsDataset.Open;

 

Note that by default there is no need to set the Manager property of nested datasets. There is a TAureliusDataset.ParentManager proeprty which defaults to true, that indicates that the Manager of the dataset will be same as the Manager of the parent dataset (which is the dataset of the linked DatasetField). In this case, whenever you Post or Delete a record in the detail dataset, the detail object will be immediately persisted in the database.

 

In case you don't want this behavior (for example, you want the details dataset to save objects in memory and only when the master object is saved you have details being saved at once), you can explicitly set the Manager property of the details dataset to nil. This will automatically set the ParentManager property to false:

 

InvoiceDataset.SetSourceList(List);
InvoiceDataset.Manager := Manager1;
// Set Manager to nil so only save items when InvoiceDataset is posted. 
// ItemsDataset.ParentManager will become false
ItemsDataset.Manager := nil
InvoiceDataset.Open;

 

As with any master-detail relationship, you can add or remove records from the detail/nested dataset, and it will add/remove items from the collection:

 

ItemsDataset.Append;

ItemsDataset.FieldByName('ProductName').AsString := 'A';

ItemsDataset.FieldByName('Price').AsCurrency := 1;

ItemsDataset.Post;

 

ItemsDataset.Append;

ItemsDataset.FieldByName('ProductName').AsString := 'B';

ItemsDataset.FieldByName('Price').AsCurrency := 1;

ItemsDataset.Post;