Complex Inheritance
This tutorial demonstrates you how to create complex inheritance hierarchies by mixing horizontal and flat mapping. 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 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. Horizontal inheritance can only be enabled for the topmost class in a hierarchy. Each immediate subclass is stored in its own table with a "copy" of the fields from the superclass. A horizontally mapped class itself, i.e. the superclass, does not have a table. Therefore, a horizontally mapped class cannot be directly persisted; only subclasses of the class can be stored in the database. For this reason, it is recommended (but not required) for horizontally mapped classes to be declared as abstract.
Modeling Complex Inheritance
For this walkthrough, a horizontal and flat inheritance mappings are mixed. The following sample inheritance hierarchy will be used:
First, a horizontal mapping is used for the Animal, Dog and Cat classes. This will result into the creation of two tables in the database Cat and Dog. In the horizontal inheritance the superclass (the root) is not represented with a table in the database. Next, flat mapping is used for the Rottweiler and WienerDog classes. That means the fields for the Rottweiler and WienerDog classes will be persisted in the Dog table.
public class FluentModelMetadataSource : FluentMetadataSource
{
protected override IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> configurations = new List<MappingConfiguration>();
MappingConfiguration<Animal> animal = new MappingConfiguration<Animal>();
animal.MapType().Inheritance( Telerik.OpenAccess.InheritanceStrategy.Horizontal );
animal.HasProperty( x => x.Name ).IsIdentity();
MappingConfiguration<Dog> dog = new MappingConfiguration<Dog>();
dog.MapType(x => new
{
BB = x.BestFriend,
Id = x.Id,
Name = x.Name
}).ToTable("Dog");
dog.HasProperty( x => x.Id ).IsIdentity(KeyGenerator.Autoinc);
MappingConfiguration<Cat> cat = new MappingConfiguration<Cat>();
cat.MapType(x => new
{
Id1 = x.Id,
ll = x.LivesLeft,
Name = x.Name
}).ToTable("Cat");
cat.HasProperty( x => x.Id ).IsIdentity( KeyGenerator.Autoinc );
MappingConfiguration<Rottweiler> rot = new MappingConfiguration<Rottweiler>();
rot.MapType(x => new
{
DE = x.DogsEaten
})
.Inheritance(Telerik.OpenAccess.InheritanceStrategy.Flat)
.ToTable("Dog");
MappingConfiguration<WienerDog> wiener = new MappingConfiguration<WienerDog>();
wiener.MapType(x => new
{
Lenght = x.Length
})
.Inheritance(Telerik.OpenAccess.InheritanceStrategy.Flat)
.ToTable("Dog");
configurations.Add( animal );
configurations.Add( dog );
configurations.Add( cat );
configurations.Add( rot );
configurations.Add( wiener );
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().Inheritance(Telerik.OpenAccess.InheritanceStrategy.Horizontal)
animal.HasProperty(Function(x) x.Name).IsIdentity()
animal.FieldNamingRules.AddPrefix = "_"
Dim dog As New MappingConfiguration(Of Dog)()
dog.MapType(Function(x) New With {Key .BB = x.BestFriend, Key .Id = x.Id, Key .Name = x.Name}).ToTable("Dog")
dog.HasProperty(Function(x) x.Id).IsIdentity(KeyGenerator.Autoinc)
dog.FieldNamingRules.AddPrefix = "_"
Dim cat As New MappingConfiguration(Of Cat)()
cat.MapType(Function(x) New With {Key .Id1 = x.Id, Key .ll = x.LivesLeft, Key .Name = x.Name}).ToTable("Cat")
cat.HasProperty(Function(x) x.Id).IsIdentity(KeyGenerator.Autoinc)
cat.FieldNamingRules.AddPrefix = "_"
Dim rot As New MappingConfiguration(Of Rottweiler)()
rot.MapType(Function(x) New With {Key .DE = x.DogsEaten}).
Inheritance(Telerik.OpenAccess.InheritanceStrategy.Flat).ToTable("Dog")
rot.FieldNamingRules.AddPrefix = "_"
Dim wiener As New MappingConfiguration(Of WienerDog)()
wiener.MapType(Function(x) New With {Key .Lenght = x.Length}).
Inheritance(Telerik.OpenAccess.InheritanceStrategy.Flat).ToTable("Dog")
wiener.FieldNamingRules.AddPrefix = "_"
configurations.Add(animal)
configurations.Add(dog)
configurations.Add(cat)
configurations.Add(rot)
configurations.Add(wiener)
Return configurations
End Function
End Class
Animal Class
public class Animal
{
public string Name {get;set;}
public int Age { get; set; }
}
Public Class Animal
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 int Id {get;set;}
public string BestFriend {get;set;}
}
Public Class Dog
Inherits Animal
Private _id As Integer
Public Property Id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
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 Id {get;set;}
public int LivesLeft {get;set;}
}
Public Class Cat
Inherits Animal
Private _id As Integer
Public Property Id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
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
WienerDog Class
public class WienerDog : Dog
{
public decimal Length {get;set;}
}
Public Class WienerDog
Inherits Dog
Private _length As Decimal
Public Property Length() As Decimal
Get
Return _length
End Get
Set(ByVal value As Decimal)
_length = value
End Set
End Property
End Class
Rottweiler Class
public class Rottweiler : Dog
{
public int DogsEaten {get;set;}
}
Public Class Rottweiler
Inherits Dog
Private _dogsEaten As Integer
Public Property DogsEaten() As Integer
Get
Return _dogsEaten
End Get
Set(ByVal value As Integer)
_dogsEaten = value
End Set
End Property
End Class