Posts Tagged ‘Inheritance’

That’s right. I have skipped part 3 for now. We will return to that. Lets take a step back and look at some inheritance and splitting scenarios that the Entity Framework supports. Relational inheritance is a way of describing your relational data in a OO form, where the rules of polymorphism hold true for your model. Splitting is a way of classifying your data so that it maps onto sets of entities in your model.

Inheritance Scenarios

 

TPT: Table per Type
Scenario

I have a 1-1 table relationship in my database that represents a base class – sub class structure

Example
  • Person is a contact
  • Business is a contact
How to
  • Drag the 2 entities onto the designer
  • Link them with the inheritance tool

Or

  • Use the context menus.

This is the model first design default behaviour.

Notes
  • Polymorphic rules apply to loading. Querying the base type will cast to subtypes along with their respective data.
TPH: Table per Hierarchy
Scenario

I have a single table in the database where sets of columns identify difference inheritance structures and there is a condition column (lookup or code) that identifies the entity type.

Example

A user table that has a lookup on user type that varies as the user passes through my user lifecycle workflow (I.E.: Anonymous -> Registered -> Made Purchase -> VIP), as he does so, more methods and options are opened up.

How To
  • Drag an entity onto the designer and link it to the table.
  • Mark this entity as abstract
  • Delete non common properties including the keying column.
  • Create another entity that derives from the base entity
  • Under the mapping set a condition/s on the switch column/s
  • Add the additional columns unique to the child entity.
Notes
  • Polymorphic rules apply to loading. Querying the base type will cast to subtypes along with their respective data.
TPC: Table per Concrete Class
Scenario

I have multiple identical tables that represent an inheritance structure. Conceptually they are the same, but structurally there is additional information that is mutually exclusive (I.E.: Relationships)

Example
  • Employee -> CurrentEmployee that maps to Employees table with relationships to Manager and Subordinates
  • Employee -> PreviousEmployee that maps to the PreviousEmployee table. It merely is a track of prior employees.
How To
  • This is not supported by the designer.
  • On the designer, create the two entities with their default mappings
  • View the designer in XML
  • Copy one of your entity elements from the CSPI layer and paste it.
  • Mark it as abstract and name it as the base type.
  • Delete all the common properties from the original entity and set its base type to your new base type.
  • For the other entity, mark its base type as your base type.
  • What this does is retains the mapping to the original for the second entity whilst classifying the conceptual entity as that of the base type.
Notes
  • Polymorphic rules apply to loading. Querying the base type will cast to subtypes along with their respective data.

Splitting Scenarios

Vertical Splitting
Scenario

We have two tables with a 1 – 1 relationship that we want to represent in a single entity. This is like TBT inheritance mapping without the inheritance structure.

Example

I have a User table with a 1 – 1 relationship with a Location table, since in my application a user is associated with a single location. I want to represent the User Entity with the users location information in it.

How To
  • Add both entities onto the designer.
  • Select and Cute the Location properties from the Location Entity
  • Paste them into the User Entity
  • Delete the Location Entity.
  • When prompted if you want to remove the Location entity from the Store layer, click No
  • Go to the mapping details on the User entity and add the Location table to the mappings list. This will automatically populate the property mappings.
Notes
  • When selecting this creates an inner join transparently
  • Because this is NOT inheritance, polymorphic loads do not apply.
Horizontal Splitting
Scenario

I have 2 similar tables with the same column names and I want only one entity. However I still want to distinguish between the two via a Boolean flag

Example

I have two tables that represent batches of data. Processed and Unprocessed. I want to easily remove a row from the Unprocessed table and insert it into the Processed table when I have finished processing it.

How To
  • Add the two entities to the designer
  • Delete the Processed entity
  • When prompted if you want to remove its data from the Store Layer, click No
  • Select the Unprocessed entity and add the Processed table to its mappings
  • Right click the Unprocessed entity and add a new scalar property called “IsProcessed” of type Boolean
  • Go to the EDMX XML, as this next step is not supported by the designer
  • In the mapping layer under the Processed ENTITY you will see 2 mapping elements, one for Processed Table and one for Unprocessed Table, under the Processed TABLE element, add a condition element
    <Condition Name=”IsProcessed” Value=”false” />
  • Under the UnProcessed TABLE element, add a condition element
    <Condition Name=”IsProcessed” Value=”true” />
Notes
  • Creates a union on the set when selecting
  • When changing the Boolean flag between conditions, the row is deleted from the one table and inserted into the other transparently.
Table Splitting
Scenario

I have one table but I want to create a navigation property to some other columns on the same entity.

Example

I have a Person entity with a picture column on it. I do not want to load this image each time I query the entity. Rather I want to have a Picture property that I can navigate to and defer the loading of the image.

How To
  • Add the entity to the designer
  • Copy and paste the entity
  • Rename the second entity
  • Pluralize the second entities Entity Set Name from its properties.
  • Delete all unwanted properties from the second entity
  • Set the mapping on the second entity to the same Store as the first.
  • Delete opposite properties on the first entity
  • Add an association element to the designer
  • Set the multiplicity to 1 – 1
  • Double click on the association entity
  • Set the Principal to the second entity
Notes
  • Setting the contexts ContextOptions.LazyLoadingEnabled = false will cause the entity to NOT load the navigation property EVEN when it is navigated to. It will instead return null.
  • With lazy loading enabled this will query the navigation property when it is called, as per expected lazy load behaviour
  • Using the Include(string path) method on the query allows you to force the loading of the navigation property upfront.