Entity Framework (TPT): Part II

Table Inheritance in Entity Framework

 
In OOP, inheritance is used to reduce unnecessary code. We can also achieve inheritance using the Entity Framework.
 
Entity Framework supports three different types of inheritance.
  1. THP - Table Per Hierarchy
  2. TPT - Table Per Type
  3. TPC - Table Per Concrete Class

Table per Type

 
Table-per-type inheritance uses a separate table in the database to maintain data and uses a single entity type in the Entity Framework. In other words, there is a single entity set in the Entity Framework for many database tables.
 
The main advantage of Table per Type is that the SQL schema is normalized as you want. In addition, model enhancement is very straightforward i.e. only modifying the base class or adding a new subclass on modifying or adding a new table.
 

Inheritance using TPT

 
Step 1: Create an Entity Model from the database.
 
TPT1.gif
 
Step 2: Delete Entity Relation.
 
TPT2.gif
 
Step 3: Add inheritances
 
TPT3.gif
 
TPT4.gif
 
Step 4: Delete derived entity key property.
 
TPT5.gif
 
Delete derived entities (customer and Employee) key property (in this case CustomerID and EmployeeId respectively). These key properties are mapped with PersonId in the next step.
 
Step 5: Map Key property of derived type with the key property of Base Type.
 
TPT6.gif
 

Update EDMX Manually

  1. Storage Model
     
    In the storage Model, Define Entity type, Key, and properties that are the same as the database. There is no definition for derived in the storage model.
    1. <EntityContainer Name="AdventureWorksModelStoreContainer">  
    2.           <EntitySet Name="Customer" EntityType="AdventureWorksModel.Store.Customer" store:Type="Tables" Schema="dbo" />  
    3.           <EntitySet Name="Employees" EntityType="AdventureWorksModel.Store.Employees" store:Type="Tables" Schema="dbo" />  
    4.           <EntitySet Name="Person" EntityType="AdventureWorksModel.Store.Person" store:Type="Tables" Schema="dbo" />  
    5.           <AssociationSet Name="FK_Customer_Person" Association="AdventureWorksModel.Store.FK_Customer_Person">  
    6.             <End Role="Person" EntitySet="Person" />  
    7.             <End Role="Customer" EntitySet="Customer" />  
    8.           </AssociationSet>  
    9.           <AssociationSet Name="FK_Employees_Person" Association="AdventureWorksModel.Store.FK_Employees_Person">  
    10.             <End Role="Person" EntitySet="Person" />  
    11.             <End Role="Employees" EntitySet="Employees" />  
    12.           </AssociationSet>  
    13. </EntityContainer>  
    14.   
    15. <EntityType Name="Customer">  
    16.           <Key>  
    17.             <PropertyRef Name="CustomerID" />  
    18.           </Key>  
    19.           <Property Name="CustomerID" Type="int" Nullable="false" />  
    20.           <Property Name="CustomerCode" Type="varchar" Nullable="false" MaxLength="50" />  
    21.           <Property Name="CustomerName" Type="varchar" Nullable="false" MaxLength="50" />  
    22.           <Property Name="IsActive" Type="bit" Nullable="false" />  
    23. </EntityType>  
    24.   
    25. <EntityType Name="Employees">  
    26.           <Key>  
    27.             <PropertyRef Name="EmployeeId" />  
    28.           </Key>  
    29.           <Property Name="EmployeeId" Type="int" Nullable="false" />  
    30.           <Property Name="EmployeeCode" Type="varchar" Nullable="false" MaxLength="25" />  
    31.           <Property Name="Name" Type="varchar" Nullable="false" MaxLength="150" />  
    32.           <Property Name="DepartmentId" Type="int" Nullable="false" />  
    33.           <Property Name="Isactive" Type="bit" Nullable="false" />  
    34.         </EntityType>  
    35.         <EntityType Name="Person">  
    36.           <Key>  
    37.             <PropertyRef Name="PersonId" />  
    38.           </Key>  
    39.           <Property Name="PersonId" Type="int" Nullable="false" />  
    40.           <Property Name="EmailAddress" Type="varchar" MaxLength="100" />  
    41. </EntityType>  
    42.   
    43. <Association Name="FK_Customer_Person">  
    44.           <End Role="Person" Type="AdventureWorksModel.Store.Person" Multiplicity="1" />  
    45.           <End Role="Customer" Type="AdventureWorksModel.Store.Customer" Multiplicity="0..1" />  
    46.           <ReferentialConstraint>  
    47.             <Principal Role="Person">  
    48.               <PropertyRef Name="PersonId" />  
    49.             </Principal>  
    50.             <Dependent Role="Customer">  
    51.               <PropertyRef Name="CustomerID" />  
    52.             </Dependent>  
    53.           </ReferentialConstraint>  
    54. </Association>  
    55.   
    56. <Association Name="FK_Employees_Person">  
    57.           <End Role="Person" Type="AdventureWorksModel.Store.Person" Multiplicity="1" />  
    58.           <End Role="Employees" Type="AdventureWorksModel.Store.Employees" Multiplicity="0..1" />  
    59.           <ReferentialConstraint>  
    60.             <Principal Role="Person">  
    61.               <PropertyRef Name="PersonId" />  
    62.             </Principal>  
    63.             <Dependent Role="Employees">  
    64.               <PropertyRef Name="EmployeeId" />  
    65.             </Dependent>  
    66.           </ReferentialConstraint>  
    67. </Association> 
  2. Conceptual Model
     
    Define base type entity and derived type entity set in the conceptual model.
    1. <EntityType Name="Customer" BaseType="AdventureWorksModel.Person">  
    2.           <Property Type="String" Name="CustomerCode" Nullable="false" MaxLength="50" FixedLength="false" Unicode="false" />  
    3.           <Property Type="String" Name="CustomerName" Nullable="false" MaxLength="50" FixedLength="false" Unicode="false" />  
    4.           <Property Type="Boolean" Name="IsActive" Nullable="false" />  
    5. </EntityType>  
    6.   
    7. <EntityType Name="Employee" BaseType="AdventureWorksModel.Person">  
    8.           <Property Type="String" Name="EmployeeCode" Nullable="false" MaxLength="25" FixedLength="false" Unicode="false" />  
    9.           <Property Type="String" Name="Name" Nullable="false" MaxLength="150" FixedLength="false" Unicode="false" />  
    10.           <Property Type="Int32" Name="DepartmentId" Nullable="false" />  
    11.           <Property Type="Boolean" Name="Isactive" Nullable="false" />  
    12.           <NavigationProperty Name="Department" Relationship="AdventureWorksModel.FK_Employees_Department" FromRole="Employee" ToRole="Department" />  
    13. </EntityType>  
    14.   
    15. <EntityType Name="Person">  
    16.           <Key>  
    17.             <PropertyRef Name="PersonId" />  
    18.           </Key>  
    19.           <Property Type="Int32" Name="PersonId" Nullable="false" />  
    20.           <Property Type="String" Name="EmailAddress" MaxLength="100" FixedLength="false" Unicode="false" />  
    21. </EntityType> 
  3. Mapping Model
     
    Map the base entity type and derived types in the same EntitySetMapping element in this section. Map inherited properties to the table.
     
    Use the IsTypeOf syntax when setting the value of the TypeName attribute
    1. <EntitySetMapping Name="People">  
    2.             <EntityTypeMapping TypeName="IsTypeOf(AdventureWorksModel.Person)">  
    3.               <MappingFragment StoreEntitySet="Person">  
    4.                 <ScalarProperty Name="PersonId" ColumnName="PersonId" />  
    5.                 <ScalarProperty Name="EmailAddress" ColumnName="EmailAddress" />  
    6.               </MappingFragment>  
    7.             </EntityTypeMapping>  
    8.             <EntityTypeMapping TypeName="IsTypeOf(AdventureWorksModel.Customer)">  
    9.               <MappingFragment StoreEntitySet="Customer">  
    10.                 <ScalarProperty Name="PersonId" ColumnName="CustomerID" />  
    11.                 <ScalarProperty Name="CustomerCode" ColumnName="CustomerCode" />  
    12.                 <ScalarProperty Name="CustomerName" ColumnName="CustomerName" />  
    13.                 <ScalarProperty Name="IsActive" ColumnName="IsActive" />  
    14.               </MappingFragment>  
    15.               </EntityTypeMapping>  
    16.             <EntityTypeMapping TypeName="IsTypeOf(AdventureWorksModel.Employee)">  
    17.               <MappingFragment StoreEntitySet="Employees">  
    18.                 <ScalarProperty Name="PersonId" ColumnName="EmployeeId" />  
    19.                 <ScalarProperty Name="EmployeeCode" ColumnName="EmployeeCode" />  
    20.                 <ScalarProperty Name="Name" ColumnName="Name" />  
    21.                 <ScalarProperty Name="DepartmentId" ColumnName="DepartmentId" />  
    22.                 <ScalarProperty Name="Isactive" ColumnName="Isactive" />  
    23.               </MappingFragment>  
    24.               </EntityTypeMapping>  
    25. </EntitySetMapping> 
In the next article, we will learn about TPC (Table per Concrete Class) and how to add it in EDMX.


Similar Articles