Show/Hide Toolbars

TMS Aurelius Documentation

Navigation: Data Binding - TAureliusDataset > Using Fields

Heterogeneous Lists (Inheritance)

Scroll Prev Top Next More

When providing objects to the dataset, the list provided might have objects instances of different classes. This happens for example when you perform a polymorphic query. Suppose you have a class hierarchy which base class is TAnimal, and descendant classes are TDog, TMammal, TBird, etc.. When you perform a query like this:


Animals := Manager.Find<TAnimal>.List;


You might end up with a list of objects of different classes like TDog or TBird. Suppose for example TDog class has a DogBreed property, but TBird does not. Still, you need to create a field named "DogBreed" so you can display it in a grid or edit that property in a form.


TAureliusDataset allows you to create fields mapped to properties that might not exist in the object. Thus, you can create a persistent field named "DogBreed", or you can change the base class of the dataset to TDog so that the default fields will include a field named "DogBreed".


To allow this feature to work well, when such a field value is requested and the property does not exist in the object, TAureliusDataset will not raise any error. Instead, the field value will be null. Thus, if you are listing the objects in a dbgrid, for example, a column associated with field "DogBreed" will display the property value for objects of class TDog, but will be empty for objects of class TBird, for example. Please note that this behavior only happens when reading the field value. If you try to set the field value and the property does not exist, an error will be raised when the record is posted. If you don't change the field value, it will be ignored.


Also note that the base class is used to create a new object instance when inserting new records (creating objects). The following code illustrates how to use a dataset associated with a TList<TAnimal> and still creating two different object types:


Animals := Manager.FindAll<TAnimal>;

DS.SetSourceList(Animals); // base class is TAnimal

DS.ObjectClass := TDog; // not base is class is TDog



DS.FieldByName('Name').AsString := 'Snoopy';

DS.FieldByName('DogBreed').AsString := 'Beagle';

DS.Post; // Create a new TDog instance


DS.ObjectClass := TBird; // change base class to TBird

DS.FieldByName('Name').AsString := 'Tweetie';

DS.Post; // Create a new TBird instance. DogBreed field is ignored