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

Using Per-Class Configuration

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.

The Fluent Mapping API allows you to map your classes by creating a static method that returns a MappingConfiguration in the respective class. When you use per-class configuration, you still need to create a class that derives from FluentMetadataSource and to override the abstract PrepareMapping method. The PrepareMapping method should just return an empty list. With this setup, during runtime the mapping will be collected from all of the classes having a static method that returns a MappingConfiguration.

Using Per-Class Configuration

The following example demonstrates you how to map the Person entity:

public class Person
{
   public int Id {get;set;}
   public string FirstName {get;set;}

   public static MappingConfiguration GetMapping()
   {
       MappingConfiguration<Person> person = new MappingConfiguration<Person>();
       person.MapType( p => new
       {
           Id = p.Id,
           FirstName = p.FirstName
       } ).ToTable( "People" );
       person.HasProperty( p => p.Id ).IsIdentity();
       return person;
   }
}
Public Class Person
    Private _id As Integer
    Public Property Id As Integer
        Get
            Return _id
        End Get
        Set(value As Integer)
            _id = value
        End Set
    End Property

    Private _firstName As String
    Public Property FirstName As String
        Get
            Return _firstName
        End Get
        Set(value As String)
            _firstName = value
        End Set
    End Property

    Public Shared Function GetMapping() As MappingConfiguration
        Dim person As New MappingConfiguration(Of Person)()
        person.MapType(Function(p) New With {Key .Id = p.Id,
            Key .FirstName = p.FirstName}).ToTable("People")
        person.FieldNamingRules.AddPrefix = "_"
        person.HasProperty(Function(p) p.Id).IsIdentity()
        Return person
    End Function
End Class

Also, when you use a per-class configuration, you can provide a configuration for the private members of the class. This is something that's not achievable when you provide a mapping in the PrepareMapping method.

public class Person
{
   private string lastName;
   public int Id {get;set;}
   public string FirstName {get;set;}

   public static MappingConfiguration GetMapping()
   {
       MappingConfiguration<Person> person = new MappingConfiguration<Person>();
       person.MapType( p => new
       {
           Id = p.Id,
           FirstName = p.FirstName,
           LastName = p.lastName
       } ).ToTable( "People" );
       person.HasProperty( p => p.Id ).IsIdentity();
       return person;
   }
}
Public Class Person
    Private _lastName As String

    Private _id As Integer
    Public Property Id As Integer
        Get
            Return _id
        End Get
        Set(value As Integer)
            _id = value
        End Set
    End Property

    Private _firstName As String
    Public Property FirstName As String
        Get
            Return _firstName
        End Get
        Set(value As String)
            _firstName = value
        End Set
    End Property

    Public Shared Function GetMapping() As MappingConfiguration
        Dim person As New MappingConfiguration(Of Person)()
        person.MapType(Function(p) New With {Key .Id = p.Id,
                                             Key .FirstName = p.FirstName,
                                             Key .LastName = p._lastName}).ToTable("People")
        person.FieldNamingRules.AddPrefix = "_"
        person.HasProperty(Function(p) p.Id).IsIdentity()
        Return person
    End Function
End Class

Using Per-Class Configuration and the PrepareMapping Method

An interesting case is when you have a per-class configuration, a custom FluentMetadataSource, and you provide a mapping configuration for the target class in both of the places. In this case a higher priority will have the mapping in the PrepareMapping method. All other property (fields) mappings which are not provided in the PrepareMapping method will be taken from the static method provided by the class. Note that in this case, any additional mapping configurations in the static method will be skipped. In the following example, you have a custom FluentMetadataSource, where you provide a mapping configuration for the Person class.

public class FluentModelMetadataSource : FluentMetadataSource
{
   protected override IList<MappingConfiguration> PrepareMapping()
   {
       List<MappingConfiguration> configurations = new List<MappingConfiguration>();

       MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
       personConfiguration.MapType(p => new
                                               {
                                                   Address = p.Address,
                                                   LastName = p.LastName
                                               }).ToTable("People");
       configurations.Add( personConfiguration );

       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 personConfiguration As New MappingConfiguration(Of Person)()
        personConfiguration.MapType(Function(p) New With {Key .Address = p.Address,
                                                  Key .LastName = p.LastName}).ToTable("People")
        personConfiguration.FieldNamingRules.AddPrefix = "_"

        configurations.Add(personConfiguration)
        Return configurations
    End Function
End Class

At the same time you have a static method creating MappingConfiguration in the Person class.

public class Person
{
   public string LastName { get; set; }
   public int Id {get;set;}
   public string FirstName {get;set;}
   public string Address { get; set; }

   public static MappingConfiguration GetMapping()
   {
       MappingConfiguration<Person> person = new MappingConfiguration<Person>();
       person.MapType( p => new
       {
           Id = p.Id,
           FirstName = p.FirstName
       } ).ToTable( "People" );
       person.HasProperty( p => p.Id ).IsIdentity();
       return person;
   }
}
Public Class Person
    Private _lastName As String
    Public Property LastName As String
        Get
            Return _lastName
        End Get
        Set(value As String)
            _lastName = value
        End Set
    End Property

    Private _id As Integer
    Public Property Id As Integer
        Get
            Return _id
        End Get
        Set(value As Integer)
            _id = value
        End Set
    End Property

    Private _firstName As String
    Public Property FirstName As String
        Get
            Return _firstName
        End Get
        Set(value As String)
            _firstName = value
        End Set
    End Property

    Private _address As String
    Public Property Address As String
        Get
            Return _address
        End Get
        Set(value As String)
            _address = value
        End Set
    End Property

    Public Shared Function GetMapping() As MappingConfiguration
        Dim person As New MappingConfiguration(Of Person)()
        person.MapType(Function(p) New With {Key .Id = p.Id,
                                             Key .FirstName = p.FirstName}).ToTable("People")
        person.FieldNamingRules.AddPrefix = "_"
        person.HasProperty(Function(p) p.Id).IsIdentity()

        Return person
    End Function
End Class

Several notes should be pointed for the last two code-snippets:

  • First, property configurations for the Address and LastName properties are created in the PrepareMapping method.
  • Second, property configurations for the Id and FirstName properties are created in the static GetMapping method.
  • The Id property is set as an identity field in the static GetMapping method.

In this case the Fluent Mapping API will take a look first at the PrepareMapping method - it will take the property configurations for the Address and LastName properties from there. Next, the static GetMapping method will be processed and information about the Id and FirstName configuration will be retrieved. However, the identity configuration for the Id property will be skipped by the Fluent Mapping API, because of these two reasons:

  • First, you are providing mapping for the Person object in the PrepareMapping method and for the static GetMapping method at the same time.
  • Second, the IsIdentity configuration is performed in the static GetMapping method.

For example, if you set the Id property as an identity field in the PrepareMapping method, then this instruction will be processed by the Fluent Mapping API. Also, if you set the Id property as an identity field in the static GetMapping method, but at the same time you don't provide a configuration for the Person class in the PrepareMapping, then the IsIdentity configuration for the Id property will be processed again. In summary, if you provide mapping for the same object in both of the places, then any additional property configurations in the static method will be skipped.

Another case that should be considered is when you provide a mapping configuration for the same property in both of the places. In this case an exception will be thrown.