Table Per Hierarchy Inheritance in Entity Framework

January 24, 2010

Table Per Hierarchy Inheritance in Entity Framework

In the second Table Per Hierarchy Inheritance in Entity Framework
inheritance mappings
tutorials I’m going to
write about the
Table Per Hierarchy
(TPH) inheritance
mapping. If you want to read
about the first mapping I showed go to the Table Per Type post from
here.

Table Per Hierarchy Definition

In TPH the inheritance tree is create through one table only.
The TPH inheritance depends on a conditional mapping which is
defined by a condition such as a discriminator database field.
The condition is used to define records as different types.
For example, in the following database schema the Person table
includes a TPH inheritance:

Database Schema
As you can see the table holds two different fields from two
different types: HireDate (which belong to a professor type)
and EnrollmentDate (which belong to student type). The table
also includes an integer discriminator field which is called PersonType.
When PersonType equals 1 the person type is a professor and when 
it is 2 the type is student.

TPH Example

The following steps will help you to understand how you can create
a TPH inheritance mapping. I’m going to use the exactly database
from the first figure I showed.

Step 1 
The first step is to create the Entity Data Model from the database.
Here is the EDM I’m going to use in the example:
Entity Designer Diagram 
We are going to use only the Person entity for the TPH demonstration.

Step 2
From the designer surface use the Add –> Entity and add two entities:
Professor and Student.
Add New Entities
Make Person entity their base type.
Add Professor 
After that the model should look like:
Entity Designer Diagram 1 

Step 3
Move the HireDate property to the Professor entity and the
EnrollmentDate property to the Student entity. Also remove
the PersonType property from Person because it is going to
be our discriminator field. 
Entity Designer Diagram 2 

Step 4
In the Mapping Details View map the Student entity and the
Professor entity to the Person table. Also map the relevant
properties to the fields in the database. The following figure
shows how to map the student entity:
Map The Student Entity 

Step 5
Add a condition to the entities using the Mapping Details View. The
condition should be on the PersonType field and should indicate that
if PersonType equals 1 the person is a Professor type and if the
PersonType equals 2 the person type is a Student. the following
figure shows how to do it in the Student type:
Add Condition 

Step 6
Since Person is a base type which is an abstract type we need to
indicate that it is abstract. Point on the Person entity and press
F4 to open it’s properties dialog. In the dialog turn the abstract
flag to True.
Person Properties

Step 7
Test the inheritance mapping. The following code will print the
number of people in the database and also the number of professors
and students:

using (var context = new SchoolEntities())
{
    var query = from person in context.People
                select person;
    Console.WriteLine("All People: " + query.Count().ToString());
 
    var query1 = from student in context.People.OfType<Student>()
                select student;
    Console.WriteLine("Students: " + query1.Count().ToString());
 
    var query2 = from proffesor in context.People.OfType<Professor>()
                select proffesor;
    Console.WriteLine("Professors: " + query2.Count().ToString());
}
 
Console.ReadLine();

Summary

Lets sum up, in the post I explained what is Table Per Hierarchy

inheritance
and showed how we can create that inheritance

in a specific model. The use of TPH is common and sometimes

can lead to very big tables which include a lot of fields. Since it is

a bad habit to create very big tables, I suggest to use TPH with TPT.

In the last post in this series I’m going to explain what is

Table Per Concrete Type inheritance and how to use it in EF.

DotNetKicks Image
Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

8 comments

  1. Steve WarwickFebruary 4, 2010 ב 23:28

    Will this work with POCO objects?

    Reply
  2. Gil FinkFebruary 5, 2010 ב 8:24

    Hi Steve,
    You can use TPT with POCO objects.

    Reply
  3. tim downeyFebruary 25, 2010 ב 14:54

    I have tried to replicate this and it does not work in Visual Studio 2008 SP1. Can you tell me what version of the product you used to create this?

    I get consistent errors when I try and map the discriminator field with a condition.

    Also you cannot seem to use a PK field as the discriminator field in the condition.

    Reply
  4. Gil FinkFebruary 25, 2010 ב 15:45

    @tim downey,
    I have tested it in both versions (EF1 and EF4) and it is working. It is the same example that I’m showing in sessions that I perform.
    What type of field do you try to use as discriminator?
    Also as you wrote you can’t use PK as a disicriminator.

    Reply
  5. ErikMarch 23, 2010 ב 17:43

    Hello,

    everybody seems to use the same sample where the database is first created then a model extracted from it, then the person table is used to build the inheritance. This work alright.
    The question is: how about creating the model FIRST.
    In VS 2010 RC there seems to be only a TablePerTypeStrategy.xaml delivered.
    If you modify the edmx file in the designer and try to regenerate the script to build the database, then the TPH is destroyed and replaced by a TPT database.
    Is there a way of doing this, for instance by downloading what should be a TablePerHierarchyStrategy.xaml or doing something else?

    Erik

    Reply
  6. Gil FinkMarch 23, 2010 ב 19:53

    Hi Erik,

    A very good question indeed. EF4′s model first comes with only TablePerTypeStrategy but… there is a solution. You can use the extension manager in VS2010 in order to download the Entity Designer Database Generation Power Pack. It include more strategies including the TPH strategy. Go to the following link for more details: http://visualstudiogallery.msdn.microsoft.com/en-us/df3541c3-d833-4b65-b942-989e7ec74c87
    It is a very recommended extension for EF and it comes from Microsoft.

    Enjoy

    Reply
  7. ErikMarch 24, 2010 ב 12:30

    Hi Gil,

    thanks a lot: that was exactly what I needed.
    I just had to copy and modify the two tt files in order to change the defaut discriminator column type and value.

    Erik

    Reply
  8. ToineApril 19, 2010 ב 13:50

    Suppose you have loaded a Student into the object context. How can you make him a Professor?

    Reply