Flat Inheritance
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
This tutorial teaches you how to model flat inheritance mapping by using the Fluent Mapping API. With flat mapping, fields from the subclasses are mapped to a superclass table. Flat mapping is the simplest and is usually the fastest option so it is the default. In Flat mapping, the entire class hierarchy is persisted into a single table. That includes everything from an interface/abstract class at the top, all the way down to implementation classes at the bottom.
Modeling Flat Inheritance
The following example demonstrates how to model flat inheritance for the Animal hierarchy. The specific point here is that you have to specify a primary key only for the root class in the hierarchy. In this case, this is the Animal class and the primary key is the AnimalId property. All derived classes (e.g. Cat and Dog) will use the primary key of the base (root) class. Take a look at the way the inheritance strategy is specified. You need to specify it by using the Inheritance method for each of the derived types.
There are two important things that should be pointed out here: When you model Flat inheritance, all types should be mapped to the same table. Second, all derived types must have flat mapping explicitly specified.
public class FluentModelMetadataSource : FluentMetadataSource
{
protected override IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> configurations = new List<MappingConfiguration>();
MappingConfiguration<Animal> animal = new MappingConfiguration<Animal>();
animal.MapType().ToTable( "Animal" );
animal.HasProperty( x => x.AnimalId ).IsIdentity( KeyGenerator.Autoinc );
MappingConfiguration<Dog> dog = new MappingConfiguration<Dog>();
dog.MapType( x => new
{
BB = x.BestFriend
} )
.Inheritance( Telerik.OpenAccess.InheritanceStrategy.Flat )
.ToTable( "Animal" );
MappingConfiguration<Cat> cat = new MappingConfiguration<Cat>();
cat.MapType( x => new
{
x.LivesLeft
} )
.Inheritance( Telerik.OpenAccess.InheritanceStrategy.Flat )
.ToTable( "Animal" );
configurations.Add( animal );
configurations.Add( dog );
configurations.Add( cat );
return configurations;
}
}
Public Class FluentModelMetadataSource
Inherits FluentMetadataSource
Protected Overrides Function PrepareMapping() As _
System.Collections.Generic.IList(Of Telerik.OpenAccess.Metadata.Fluent.MappingConfiguration)
Dim configurations As List(Of MappingConfiguration) = New List(Of MappingConfiguration)()
Dim animal As New MappingConfiguration(Of Animal)()
animal.MapType().ToTable("Animal")
animal.FieldNamingRules.AddPrefix = "_"
animal.HasProperty(Function(x) x.AnimalId).IsIdentity(KeyGenerator.Autoinc)
Dim dog As New MappingConfiguration(Of Dog)()
dog.FieldNamingRules.AddPrefix = "_"
dog.MapType(Function(x) New With {Key .BB = x.BestFriend}).
Inheritance(Telerik.OpenAccess.InheritanceStrategy.Flat).
ToTable("Animal")
Dim cat As New MappingConfiguration(Of Cat)()
cat.FieldNamingRules.AddPrefix = "_"
cat.MapType(Function(x) New With {Key x.LivesLeft}).
Inheritance(Telerik.OpenAccess.InheritanceStrategy.Flat).
ToTable("Animal")
configurations.Add(animal)
configurations.Add(dog)
configurations.Add(cat)
Return configurations
End Function
End Class
In Flat mapping, the entire class hierarchy is persisted to a single table. That includes everything from an interface/abstract class at the top, all the way down to implementation classes at the bottom. When you update your database schema to the latest model state, one table will be create - Animal.
If you take a look at the Animal table, you will see one additional column named voa_class. This is the discriminator column. Normally a discriminator column is required for flat and vertical inheritance. The discriminator column used to identify the type of each row with flat and vertical mapping is normally mapped to a SQL INTEGER but this can be changed. The default name for the discriminator column is voa_class. The name of the discriminator column can be changed, too. For more information, take a look at How to: Set Advanced Properties.
Animal Class
public class Animal
{
public int AnimalId { get; set; }
public string Name {get;set;}
public int Age { get; set; }
}
Public Class Animal
Private _animalId As Integer
Public Property AnimalId As Integer
Get
Return _animalId
End Get
Set(value As Integer)
_animalId = value
End Set
End Property
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _age As Integer
Public Property Age As Integer
Get
Return _age
End Get
Set(value As Integer)
_age = value
End Set
End Property
End Class
Dog Class
public class Dog : Animal
{
public string BestFriend {get;set;}
}
Public Class Dog
Inherits Animal
Private _bestFriend As String
Public Property BestFriend() As String
Get
Return _bestFriend
End Get
Set(ByVal value As String)
_bestFriend = value
End Set
End Property
End Class
Cat Class
public class Cat : Animal
{
public int LivesLeft {get;set;}
}
Public Class Cat
Inherits Animal
Private _livesLeft As Integer
Public Property LivesLeft() As Integer
Get
Return _livesLeft
End Get
Set(ByVal value As Integer)
_livesLeft = value
End Set
End Property
End Class