Data Access has been discontinued. Please refer to this page for more information.

Complex 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 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