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
C#csharp | Copy Code |
---|---|
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; } } |
Visual Basic | Copy Code |
---|---|
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
C#csharp | Copy Code |
---|---|
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; } } |
Visual Basic | Copy Code |
---|---|
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 |
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
C#csharp | Copy Code |
---|---|
[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; } } |
Visual Basic | Copy Code |
---|---|
<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
C#csharp | Copy Code |
---|---|
[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; } } |
Visual Basic | Copy Code |
---|---|
[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; } } |
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>
FluentMappingBuilder class methods are used for mapping inheritance hierarchies.
TPH Mapping
C#csharp | Copy Code |
---|---|
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); |
Visual Basic | Copy Code |
---|---|
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
C#csharp | Copy Code |
---|---|
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); |
Visual Basic | Copy Code |
---|---|
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) |