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

How to: Extend Fluent Models Using Code-Only Mapping

This topic demonstrates how to extend an existing fluent model with new types by using Code-Only Mapping:

  1. Extending a Fluent Model with New Artificial Types
  2. Extending a Fluent Model with New CLR Types
  3. Modifying the FluentMetadataSource Class
  4. Extending the FluentModelContext
  5. Creating a New FluentModelContext Instance

Extending a Fluent Model with New Artificial Types

This section shows how to extend the fluent model with new artificial types. Adding new artificial types to an existing fluent model is straight-forward. You can create the new artificial types in the PrepareMapping model. In the following example, a new artificial type named Employee is created.

MappingConfiguration employeeConfiguration = new MappingConfiguration( "Employee", "EmployeeNamespace" );
employeeConfiguration.HasArtificialPrimitiveProperty<int>( "Id" ).IsIdentity( KeyGenerator.Autoinc );
employeeConfiguration.HasArtificialStringProperty( "Name" );
employeeConfiguration.HasArtificialPrimitiveProperty<int>( "Age" );
Dim employeeConfiguration As New MappingConfiguration("Employee", "EmployeeNamespace")
employeeConfiguration.HasArtificialPrimitiveProperty(Of Integer)("Id").IsIdentity(KeyGenerator.Autoinc)
employeeConfiguration.HasArtificialStringProperty("Name")
employeeConfiguration.HasArtificialPrimitiveProperty(Of Integer)("Age")

Extending a Fluent Model with New CLR Types

This section demonstrates how to extend the fluent model with a new CLR type - the Person class. Again, in order to extend your fluent model with new CLR types, you have to create the mapping in the PrepareMapping method. The code is straight-forward. First a new instance of the MappingConfiguration<T> class is created. Next, by using the default mapping functionality, the Person type is mapped. For more information, check out the Mapping CLR Types section.

MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
personConfiguration.MapType( p => new
    {
       PersonId = p.Id,
       LastName = p.LastName,
       FirstName = p.FirstName,
       Contact = p.Address
    } ).ToTable( "People" );
personConfiguration.HasProperty( p => p.Id ).IsIdentity( KeyGenerator.Autoinc );
Dim personConfiguration As New MappingConfiguration(Of Person)()
personConfiguration.MapType(Function(p) New With {Key .PersonId = p.Id,
    Key .LastName = p.LastName,
    Key .FirstName = p.FirstName,
    Key .Contact = p.Address}).ToTable("People")
personConfiguration.HasProperty(Function(p) p.Id).IsIdentity(KeyGenerator.Autoinc)
personConfiguration.FieldNamingRules.AddPrefix = "_"

Modifying the FluentMetadataSource Class

Basically, in this scenario, you are going to mix Code-Only Mapping API and Fluent Model. In other words, you are going to combine two mapping sources. The FluentMetadataSource class exposes a constructor that allows you initializes a new instance of the FluentMetadataSource class with an existing metadata container, i.e. the fluent model metadata. There is one very important note that should be pointed here: the MyFluentMetadataSource class defines a constructor accepting a MetadataContainer instance. You will have to pass the MetadataContainer that describes the existing fluent model.

Having this in mind, here's a sample implementation of the FluentMetadataSource class:

public class FluentModelMetadataSource : FluentMetadataSource
{
    public FluentModelMetadataSource()
    {
    }
    public FluentModelMetadataSource( MetadataContainer existingModel ) :
           base( existingModel )
    {
    }
    protected override IList<MappingConfiguration> PrepareMapping()
    {
        List<MappingConfiguration> configurations = new List<MappingConfiguration>();
        MappingConfiguration employeeConfiguration = 
            new MappingConfiguration( "Employee", "EmployeeNamespace" );
        employeeConfiguration.HasArtificialPrimitiveProperty<int>( "Id" ).
            IsIdentity( KeyGenerator.Autoinc );
        employeeConfiguration.HasArtificialStringProperty( "Name" );
        employeeConfiguration.HasArtificialPrimitiveProperty<int>( "Age" );
        MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
        personConfiguration.MapType( p => new
            {
                PersonId = p.Id,
                LastName = p.LastName,
                FirstName = p.FirstName,
                Contact = p.Address
            } ).ToTable( "People" );
        personConfiguration.HasProperty( p => p.Id ).IsIdentity( KeyGenerator.Autoinc );
        configurations.Add( employeeConfiguration );
        configurations.Add( personConfiguration );
       return configurations;
    }
}
Public Class FluentModelMetadataSource
    Inherits FluentMetadataSource
    Public Sub New()
    End Sub
    Public Sub New(ByVal existingModel As MetadataContainer)
        MyBase.New(existingModel)
    End Sub
    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 employeeConfiguration As New MappingConfiguration("Employee", "EmployeeNamespace")
        employeeConfiguration.HasArtificialPrimitiveProperty(Of Integer)("Id"). _
            IsIdentity(KeyGenerator.Autoinc)
        employeeConfiguration.HasArtificialStringProperty("Name")
        employeeConfiguration.HasArtificialPrimitiveProperty(Of Integer)("Age")
        Dim personConfiguration As New MappingConfiguration(Of Person)()
        personConfiguration.MapType(Function(p) New With {Key .PersonId = p.Id,
            Key .LastName = p.LastName,
            Key .FirstName = p.FirstName,
            Key .Contact = p.Address}).ToTable("People")
        personConfiguration.HasProperty(Function(p) p.Id).IsIdentity(KeyGenerator.Autoinc)
        personConfiguration.FieldNamingRules.AddPrefix = "_"
        configurations.Add(employeeConfiguration)
        configurations.Add(personConfiguration)
        Return configurations
    End Function
End Class

The FluentModelMetadataSource class must provide parameterless constructor.

Extending the FluentModelContext

Next, you need to add a constructor in the FluentModelContext class that accept a MetadataContainers instance. For example:

public FluentModelContext(MetadataContainer fluentContainer)
   : base( DbConnection, backendConfiguration, fluentContainer )
{
}
Public Sub New(ByVal fluentContainer As MetadataContainer)
 MyBase.New(DbConnection, backendConfiguration, fluentContainer)
End Sub

Creating a New FluentModelContext Instance

The following example demonstrates how to create a new instance of the FluentModelContext by using the metadata container of the fluent model.

FluentModel domainModelContext = new FluentModel();
FluentModelMetadataSource fluentMetadata = new FluentModelMetadataSource( domainModelContext.Metadata );
FluentModelContext fluentModelContext = new FluentModelContext( fluentMetadata.GetModel() );
Dim domainModelContext As New FluentModel()
Dim fluentMetadata As New FluentModelMetadataSource(domainModelContext.Metadata)
Dim _fluentModelContext As New FluentModelContext(fluentMetadata.GetModel())

Person Class

public class Person
{
   public int Id {get;set;}
   public string FirstName {get;set;}
   public string LastName {get;set;}
   public string Address {get;set;}
}
Public Class Person
    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 _firstName As String
    Public Property FirstName() As String
        Get
            Return _firstName
        End Get
        Set(ByVal value As String)
            _firstName = value
        End Set
    End Property
    Private _lastName As String
    Public Property LastName() As String
        Get
            Return _lastName
        End Get
        Set(ByVal value As String)
            _lastName = value
        End Set
    End Property
    Private _address As String
    Public Property Address() As String
        Get
            Return _address
        End Get
        Set(ByVal value As String)
            _address = value
        End Set
    End Property
End Class