Entity Framework Modeling: Entity Splitting Part II (adding inheritance)
In Entity Splitting Part I, I illustrated how you could map multiple tables to a single entity. In the post previous to that, I illustrated how you could build a completely different conceptual layer for the same model by implementing table-per-type inheritance. These are 2 completely different modeling scenarios. Entity Splitting results in a much simpler model, while table-per-type results in a more flexible model where you are able to cast between types and take full advantage of all of the benefits of inheritance. In this post, I want to illustrate that this is not necessarily an either-or decision. You can mix and match if it meets the need of your application.
Revisiting The Data Model
As you can see from my annotations, our goal here is to create a “hybrid” model, implementing entity splitting along with table-per-type. I will create a Student entity that is sourced from 2 tables: PersonTPT and StudentTPT. I may choose to do this if there is no benefit to having a Person entity in my conceptual layer. Perhaps I am building a student system and all I ever work with are students of varying types. Now, there may be a need in my model to build out an inheritance hierarchy where the base type is Student. We can use the Student entity we implemented using entity splitting in Part I.
Revisiting the results of Part I
In Part I, we added 2 tables, PersonTPT and StudentTPT, into our model and mapped both tables to a single Student entity.
Creating the BusinessStudent Entity and implementing inheritance
The steps below follow pretty closely the steps laid out in my table-per-type post.
Step 1: Add the BusinessStudentTPT table to the model
In the model browser, right-click and choose ‘Update Model from Database…’
Choose the BusinessStudentTPT table
It will look like this:
Step 2: Rename the entity
Step 3: Remove the default relationship
Step 4: Create the inheritance relationship
When you are done, the designer should look like this:
Step 5: Delete the derived-entities key properties
When we added the BusinessStudentTPT table, the designer looked at the table schema and added a property for each table column, including one for the PersonID column. The PersonID is a key between the entities and will be inherited from the Student entity. Therefore, we do not need this property set on each of the derived entities. Simply single-click on PersonID on BusinessStudent and press delete.
Step 6: Map the PersonID column to the inherited PersonID property
In step5, we deleted the PersonID property on the BusinessStudent entity, because it is inheriting this property from the base. Because we deleted this property, the PersonID column from the underlying BusinessStudentTPT table is no longer mapped. We need to map it to the inherited PersonID property. Simply choose the PersonID from the dropdown box.
We are done and can now test our model.
Consume the hybrid Model
There are a couple of ways to illustrate how to exploit our new model. In the below code, you can see that we are able to iterate over our Student entities and access properties that are sourced from the 2 tables: PersonTPT and StudentTPT. This is thanks to entity splitting. You can also see that I am doing a type check and if the type is BusinessStudent, we will do some additional processing. In this case, simply writing some BusinessStudent-centric information to the console.
Here is the output:
Another option would be to change our query to only return BusinessStudent types:
It should be clear from this post that you are able to take advantage of both entity splitting and table-per-type inheritance if the need suits you.