LinqConnect Documentation
In This Topic
    Inheritance Mapping
    In This Topic

    LinqConnect supports two kinds of inheritance hierarchy: Table Per Hierarchy (TPH) and Table Per Type (TPT). This topic describes how to map both of these kinds.

    TPH Classes



    public class TphRoot
    {
        public int Id { get; set; }
        public string Root_Value { get; set; }
        public string Discriminator_Value { get; set; }
    }
     
    public class TphA : TphRoot
    {
        public byte[] A_Value { get; set; }
    }
     
    public class TphB : TphRoot
    {
        public DateTime B_Value { get; set; }
    }
     
    public class TphB1 : TphB
    {
        public char B1_Value { get; set; }
    }
     
    public class TphB2 : TphB
    {
        public TimeSpan B2_Value { get; set; }
    }
    Public Class TphRoot
        Public Property Id As Integer
        Public Property Root_Value As String
        Public Property Discriminator_Value As String
    End Class
     
    Public Class TphA
        Inherits TphRoot
     
        Public Property A_Value As Byte()
    End Class
     
    Public Class TphB
        Inherits TphRoot
     
        Public Property B_Value As DateTime
    End Class
     
    Public Class TphB1
        Inherits TphB
     
        Public Property B1_Value As Char
    End Class
     
    Public Class TphB2
        Inherits TphB
     
        Public Property B2_Value As TimeSpan
    End Class
    

    TPT Classes



    public class TptRoot
    {
        public int Id { get; set; }
        public string Root_Value { get; set; }
    }
     
    public class TptA : TptRoot
    {
        public string A_Value { get; set; }
    }
     
    public class TptB : TptRoot
    {
        public string B_Value { get; set; }
    }
     
    public class TptB1 : TptB
    {
        public string B1_Value { get; set; }
    }
     
    public class TptB2 : TptB
    {
        public string B2_Value { get; set; }
    }
    Public Class TptRoot
        Public Property Id As Integer
        Public Property Root_Value As String
    End Class
     
    Public Class TptA
        Inherits TptRoot
     
        Public Property A_Value As String
    End Class
     
    Public Class TptB
        Inherits TptRoot
     
        Public Property B_Value As String
    End Class
     
    Public Class TptB1
        Inherits TptB
     
        Public Property B1_Value As String
    End Class
     
    Public Class TptB2
        Inherits TptB
     
        Public Property B2_Value As String
    End Class
    

    Table per type hierarchy

    Attribute Mapping

    When using attribute mapping, inheritance relationship is specified with the InheritanceMapping and InheritanceColumnMapping attributes. This attributes have the following properties.

    You shoud use InheritanceMapping attribute to specify all the hierarchy types on the root class. For TPT hierarchy, the root type can be omitted.

    InheritanceColumnMapping attribute is used for TPT hierarchies. It specifies the correspondence between the primary key columns of the base and derived entity classes.

    InheritanceMapping attribute properties:

    Property Type Description
    Code String The discriminator column should have the specified Code value to be an instance of this class.
    Type Type Type of the entity class, mapped to the table.
    IsDefault Boolean Determines whether the specified type is the default type of the hierarchy. If the discriminator column has a value that dows not correspond to any of the hierarchy discriminator values, this row is considered to be an instance of the default hierarchy class.

    InheritanceColumnMapping attribute is used for TPT hierarchies. It specifies the correspondence between the primary key columns of the base and derived entity classes.

    InheritanceColumnMapping attribute properties:

    Property Type Description
    BaseColumnName String Type of the entity class, mapped to the table.
    ColumnName String Determines whether the specified type is the default type of the hierarchy. If the discriminator column has the value that dows not correspond to any of the hierarchy discriminator values, this row is considered to be an instance of the default hierarchy class.

    TPH Mapping



    [Table(Name = "TPH_TABLE")]
    [InheritanceMapping(Code = "R", Type = typeof(TphRoot), IsDefault = true)]
    [InheritanceMapping(Code = "A", Type = typeof(TphA))]
    [InheritanceMapping(Code = "B", Type = typeof(TphB))]
    [InheritanceMapping(Code = "B1", Type = typeof(TphB1))]
    [InheritanceMapping(Code = "B2", Type = typeof(TphB2))]
    public class TphRoot
    {
     
        [Column(Name = "ID", IsPrimaryKey = true)]
        public int Id { get; set; }
     
        [Column]
        public string Root_Value { get; set; }
     
        [Column(IsDiscriminator = true, CanBeNull = false)]
        public string Discriminator_Value { get; set; }
    }
     
    public class TphA : TphRoot
    {
        [Column]
        public byte[] A_Value { get; set; }
    }
     
    public class TphB : TphRoot
    {
        [Column]
        public DateTime B_Value { get; set; }
    }
     
    public class TphB1 : TphB
    {
        [Column]
        public char B1_Value { get; set; }
    }
     
    public class TphB2 : TphB
    {
        [Column]
        public TimeSpan B2_Value { get; set; }
    }
    <Table(Name:="TPH_TABLE")> _
    <InheritanceMapping(Code:="R", Type:=GetType(TphRoot), IsDefault:=True)> _
    <InheritanceMapping(Code:="A", Type:=GetType(TphA))> _
    <InheritanceMapping(Code:="B", Type:=GetType(TphB))> _
    <InheritanceMapping(Code:="B1", Type:=GetType(TphB1))> _
    <InheritanceMapping(Code:="B2", Type:=GetType(TphB2))> _
    Public Class TphRoot
     
        <Column(Name:="ID", IsPrimaryKey:=True)> _
        Public Property Id As Integer
     
        <Column()> _
        Public Property Root_Value As String
     
        <Column(IsDiscriminator:=True, CanBeNull:=False)> _
        Public Property Discriminator_Value As String
     
    End Class
     
    Public Class TphA
        Inherits TphRoot
     
        <Column()> _
        Public Property A_Value As Byte()
    End Class
     
    Public Class TphB
        Inherits TphRoot
     
        <Column()> _
        Public Property B_Value As DateTime
    End Class
     
    Public Class TphB1
        Inherits TphB
     
        <Column()> _
        Public Property B1_Value As Char
    End Class
     
    Public Class TphB2
        Inherits TphB
     
        <Column()> _
        Public Property B2_Value As TimeSpan
    End Class
    

    TPT Mapping



    [Table(Name = "TPT_ROOT")]
    [InheritanceMapping(Type = typeof(TptA))]
    [InheritanceMapping(Type = typeof(TptB))]
    [InheritanceMapping(Type = typeof(TptB1))]
    [InheritanceMapping(Type = typeof(TptB2))]
    public class TptRoot
    {
     
        [Column(Name = "ID", IsPrimaryKey = true)]
        public int Id { get; set; }
     
        [Column]
        public string Root_Value { get; set; }
    }
     
    [Table(Name = "TPT_A")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "A_ID")]
    public class TptA : TptRoot
    {
        [Column]
        public string A_Value { get; set; }
    }
     
    [Table(Name = "TPT_B")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "B_ID")]
    public class TptB : TptRoot
    {
        [Column]
        public string B_Value { get; set; }
    }
     
    [Table(Name = "TPT_B1")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "B1_ID")]
    public class TptB1 : TptB
    {
        [Column]
        public string B1_Value { get; set; }
    }
     
    [Table(Name = "TPT_B2")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "B2_ID")]
    public class TptB2 : TptB
    {
        [Column]
        public string B2_Value { get; set; }
    }
    [Table(Name = "TPT_ROOT")]
    [InheritanceMapping(Type = typeof(TptA))]
    [InheritanceMapping(Type = typeof(TptB))]
    [InheritanceMapping(Type = typeof(TptB1))]
    [InheritanceMapping(Type = typeof(TptB2))]
    public class TptRoot
    {
     
        [Column(Name = "ID", IsPrimaryKey = true)]
        public int Id { get; set; }
     
        [Column]
        public string Root_Value { get; set; }
    }
     
    [Table(Name = "TPT_A")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "A_ID")]
    public class TptA : TptRoot
    {
        [Column]
        public string A_Value { get; set; }
    }
     
    [Table(Name = "TPT_B")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "B_ID")]
    public class TptB : TptRoot
    {
        [Column]
        public string B_Value { get; set; }
    }
     
    [Table(Name = "TPT_B1")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "B1_ID")]
    public class TptB1 : TptB
    {
        [Column]
        public string B1_Value { get; set; }
    }
     
    [Table(Name = "TPT_B2")]
    [InheritanceColumnMapping(BaseColumnName = "ID", ThisColumnName = "B2_ID")]
    public class TptB2 : TptB
    {
        [Column]
        public string B2_Value { get; set; }
    }
    

    XML Mapping

    Inheritance hierarchies are mapped with the Type tag and InheritanceCode and IsInheritanceDefault attributes. The IsDiscriminator attribute of the Column tag specifies the discriminator column.

    InheritanceCode attribute contains the value the discriminator column should have for a row to be an instance of this class. IsInheritanceDefault determines whether the class is the default type of the hierarchy. If the discriminator column has a value that dows not correspond to any of the hierarchy discriminator values, this row is considered to be an instance of the default hierarchy class.

    TPH Mapping

    <Table Name="TPH_TABLE">
      <Type Name="TphRoot" InheritanceCode="R" IsInheritanceDefault="true">
        <Column Name="ID" Member="Id" IsPrimaryKey="true" />
        <Column Member="Root_Value" />
        <Column Member="Discriminator_Value" CanBeNull="false" IsDiscriminator="true" />
        <Type Name="TphA" InheritanceCode="A">
          <Column Member="A_Value" />
        </Type>
        <Type Name="TphB" InheritanceCode="B">
          <Column Member="B_Value" />
          <Type Name="TphB1" InheritanceCode="B1">
            <Column Member="B1_Value" />
          </Type>
          <Type Name="TphB2" InheritanceCode="B2">
            <Column Member="B2_Value" />
          </Type>
        </Type>
      </Type>
    </Table>

    TPT Mapping

    <Table>
      <Type Name="TptRoot" TableName="TPT_ROOT">
        <Column Name="ID" Member="Id" IsPrimaryKey="true" />
        <Column Member="Root_Value" />
        <Type Name="TptA" TableName="TPT_A">
          <InheritanceColumn ThisName="A_ID" BaseName="ID" />
          <Column Member="A_Value" />
        </Type>
        <Type Name="TptB" TableName="TPT_B">
          <InheritanceColumn ThisName="B_ID" BaseName="ID" />
          <Column Member="B_Value" />
          <Type Name="TptB1" TableName="TPT_B1">
            <InheritanceColumn ThisName="B1_ID" BaseName="ID" />
            <Column Member="B1_Value" />
          </Type>
          <Type Name="TptB2" TableName="TPT_B2">
            <InheritanceColumn ThisName="B2_ID" BaseName="ID" />
            <Column Member="B2_Value" />
          </Type>
        </Type>
      </Type>
    </Table>

    Fluent Mapping

    FluentMappingBuilder class methods are used for mapping inheritance hierarchies.

    TPH Mapping



    FluentMappingBuilder builder = new FluentMappingBuilder(null);
    
    // TphRoot
    builder.Entity<TphRoot>()
        .FullTableName("TPH_TABLE")
        .PrimaryKey(p => p.Id);
    // Table Per Hierarchy (TPH) inheritance:
    builder.Entity<TphRoot>()
        .Map()
            .Discriminator(p => p.Discriminator_Value)
            .DiscriminatorValue("R")
            .IsInheritanceDefault()
        .MapChild<TphA>()
            .DiscriminatorValue("A")
        .MapChild<TphB>()
            .DiscriminatorValue("B")
        .MapChild<TphB1>()
            .DiscriminatorValue("B1")
        .MapChild<TphB2>()
            .DiscriminatorValue("B2");
    // Properties:
    builder.Entity<TphRoot>()
        .Property(p => p.Id)
            .ColumnName("ID");
    builder.Entity<TphRoot>()
        .Property(p => p.Discriminator_Value)
            .NotNullable();
    
    // TphA
    builder.Entity<TphA>()
        .Property(p => p.A_Value);
    
    // TphB
    builder.Entity<TphB>()
        .Property(p => p.B_Value);
    
    // TphB1
    builder.Entity<TphB1>()
        .Property(p => p.B1_Value);
    
    // TphB2
    builder.Entity<TphB2>()
        .Property(p => p.B2_Value);
    
    Dim builder As New FluentMappingBuilder(Nothing)
     
    ' TphRoot
    builder.Entity(Of TphRoot)() _
        .FullTableName("TPH_TABLE") _
            .PrimaryKey(Function(p) p.Id)
    ' Table Per Hierarchy (TPH) inheritance:
    builder.Entity(Of TphRoot) _
        .Map() _
            .Discriminator(Function(p) p.Discriminator_Value) _
            .DiscriminatorValue("R") _
            .IsInheritanceDefault() _
        .MapChild(Of TphA) _
            .DiscriminatorValue("A") _
        .MapChild(Of TphB) _
            .DiscriminatorValue("B") _
        .MapChild(Of TphB1) _
            .DiscriminatorValue("B1") _
        .MapChild(Of TphB2) _
            .DiscriminatorValue("B2")
    ' Properties:
    builder.Entity(Of TphRoot) _
        .Property(Function(p) p.Id) _
            .ColumnName("ID")
    builder.Entity(Of TphRoot) _
        .Property(Function(p) p.Discriminator_Value) _
            .NotNullable()
    
    ' TphA
    builder.Entity(Of TphA) _
        .Property(Function(p) p.A_Value)
    
    ' TphB
    builder.Entity(Of TphB) _
        .Property(Function(p) p.B_Value)
    
    ' TphB1
    builder.Entity(Of TphB1) _
        .Property(Function(p) p.B1_Value)
    
    ' TphB2
    builder.Entity(Of TphB2) _
        .Property(Function(p) p.B2_Value)
    

    TPT Mapping



    FluentMappingBuilder builder = new FluentMappingBuilder(null);
    
    // TptRoot
    // Table Per Type (TPT) inheritance:
    builder.Entity<TptRoot>()
        .FullTableName("TPT_ROOT")
        .PrimaryKey(p => p.Id);
    builder.Entity<TptA>()
        .FullTableName("TPT_A")
        .Map(p => new { A_ID = p.Id });
    builder.Entity<TptB>()
        .FullTableName("TPT_B")
        .Map(p => new { B_ID = p.Id });
    builder.Entity<TptB1>()
        .FullTableName("TPT_B1")
        .Map(p => new { B1_ID = p.Id });
    builder.Entity<TptB2>()
        .FullTableName("TPT_B2")
        .Map(p => new { B2_ID = p.Id });
    // Properties:
    builder.Entity<TptRoot>()
        .Property(p => p.Id)
            .ColumnName("ID");
    builder.Entity<TptRoot>()
        .Property(p => p.Root_Value);
    
    // TptA
    builder.Entity<TptA>()
        .Property(p => p.A_Value);
    
    // TptB
    builder.Entity<TptB>()
        .Property(p => p.B_Value);
    
    // TptB1
    builder.Entity<TptB1>()
        .Property(p => p.B1_Value);
    
    // TptB2
    builder.Entity<TptB2>()
        .Property(p => p.B2_Value);
    
    Dim builder As New FluentMappingBuilder(Nothing)
     
    ' TptRoot
    ' Table Per Type (TPT) inheritance:
    builder.Entity(Of TptRoot) _
        .FullTableName("TPT_ROOT") _
            .PrimaryKey(Function(p) p.Id)
    builder.Entity(Of TptA)() _
        .FullTableName("TPT_A") _
            .Map(Function(p) New With {.A_ID = p.Id})
    builder.Entity(Of TptB) _
        .FullTableName("TPT_B") _
            .Map(Function(p) New With {.B_ID = p.Id})
    builder.Entity(Of TptB1) _
        .FullTableName("TPT_B1") _
            .Map(Function(p) New With {.B1_ID = p.Id})
    builder.Entity(Of TptB2) _
        .FullTableName("TPT_B2") _
            .Map(Function(p) New With {.B2_ID = p.Id})
    ' Properties:
    builder.Entity(Of TptRoot) _
        .Property(Function(p) p.Id) _
            .ColumnName("ID")
    builder.Entity(Of TptRoot) _
        .Property(Function(p) p.Root_Value)
     
    ' TptA
    builder.Entity(Of TptA) _
        .Property(Function(p) p.A_Value)
    
    ' TptB
    builder.Entity(Of TptB) _
        .Property(Function(p) p.B_Value)
    
    ' TptB1
    builder.Entity(Of TptB1) _
        .Property(Function(p) p.B1_Value)
    
    ' TptB2
    builder.Entity(Of TptB2) _
        .Property(Function(p) p.B2_Value)