Table per Hierarchy (TPH) inheritance is the commonest and easiest type of inheritance.
In TPH the inheritance tree is created through one table only. The TPH inheritance depends on a conditional mapping which is defined by a condition such as a discriminator database field. This condition is used to define records as different types.
For example, the database contains the following table:
In this table, ClassType is the discriminator (that can be either a string or integer), which determines the specific type of the animal.
For the purpose of this example, we shall perform the following sequence of actions within the Database-First approach.
Firstly, in the Database Explorer window locate the TPH_Animal table and move it onto the diagram surface to create the TPHAnimal class. At this moment, this class includes properties that are common for all types of animals as well as animal-specific properties.
The common properties are: FoodClassification, BirthDate, Family, and Genus. These properties should remain in the TPHAnimal class, while all the other properties should be moved to the corresponding classes.
Now, we shall start by selecting and moving the snake-related properties (Length and IsAdder) from the TPHAnimal class onto the design surface. This displays the following dialog box:
In the Model Refactoring dialog box, we select New derived class, enter the name of the class (Snake) into the corresponding box and click OK.
After this, the Inheritance Editor dialog box is displayed:
At this point you have two options:
1. | customizing the Discriminator settings right in the Inheritance Editor dialog; |
2. | postponing the Discriminator settings customization until the whole hierarchy is built; the Discriminator settings customization can be implemented either via the Inheritance Editor or Entity Mapping Details dialog. |
Note |
The Discriminator options are available only for Table per Hierarchy (TPH) inheritance. |
Selecting this way will reduce the number of steps to be taken in order to customize the whole hierarchy, as certain actions will be performed automatically. So we proceed with inheritance customization and in the Inheritance Editor dialog box we set the Storage Column value to ClassType, set the Base Class Condition to 'Is Null' and set the Derived Class Condition to Snake and click OK.
After customizing the inheritance in the Inheritance Editor dialog box, as we haven't deleted the base class property and mapping, a warning message is displayed offering to delete the corresponding property from the base class. We click Yes, so the ClassType property and its mapping are deleted from the TPHAnimal class. Similarly, we create the Dog class (with the Breed property and Derived Class Condition = Dog), the Horse class (with the MaximumSpeed property and Derived Class Condition = Horse), and the Crocodile class (with the Weight property and and Derived Class Condition = Crocodile). Note that the Storage Column combo-box and the Base Class Condition are prefilled with the previously specified values. The hierarchy we have just created is valid, but let's suppose that we want the Crocodile class to contain the Length property which is similar to the Length property within the Snake class. In order to add the required property to the Crocodile class, we copy the Length property from the Snake class and paste it to the Crocodile class. The base class in the diagram area becomes invalid, and the corresponding message in the Error List window indicates that Length property of the Crocodile class is not mapped. So we call the Entity Mapping Details dialog for the Crocodile class and map the Length column to the Length property (see the Entity Mapping Details dialog below). As a result we get the final model displayed at the bottom of this topic.
|
Suppose that when creating the inheritance, we don't specify the Discriminator options in the Inheritance Editor dialog at once and just click OK. The TPH inheritance is created automatically between the Snake class and the TPHAnimal class. Similarly, we create the Dog class (with the Breed property), the Horse class (with the MaximumSpeed property), and the Crocodile class (with the Weight and Length properties, note that the latter property is copied from the Snake class). Then we call the Entity Mapping Details dialog for every derived entity one by one and set the correct Condition. After that, we call the Entity Mapping Details dialog for the base class, delete mapping for the ClassType column, and set the condition for ClassType to 'Is Null'. For the Crocodile class we also map the Length column: After this, we remove the ClassType property from the TPHAnimal class and obtain the final model:
|