Mapping CLR Types
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.
When you use default mapping, the FluentMetadataSource takes care of the property to column mapping. When you use explicit mapping you are explicitly specifying the property to column mapping. The explicit mapping gives you more control over the column naming, as well as it allows you to create partially mapped models. If you use explicit mapping configuration you have to use the second overload of the MapType method that accepts a lambda expression parameter.
This tutorial teaches you how to perform an explicit mapping configuration, as follows:
Use Explicit Mapping
The following section demonstrates how to configure the Person class by using explicit mapping. You have to use the second overload of the MapType method that accepts a lambda expression parameter.
MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
personConfiguration.MapType( p => new
{
Id = p.Id,
FirstName = p.FirstName,
LastName = p.LastName,
HomeAddress = 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 .Id = p.Id,
Key .FirstName = p.FirstName,
Key .LastName = p.LastName,
Key .HomeAddress = p.Address}).ToTable("People")
personConfiguration.HasProperty(Function(p) p.Id).IsIdentity(KeyGenerator.Autoinc)
personConfiguration.FieldNamingRules.AddPrefix = "_"
If you execute the DDL script for the previous example a new table named People with primary key Id will be created in the database. The table will have the following structure:
Fluent Mapping API allows you to map a class to more than one table in the database. Read more
Adding multiple mapping configurations for the same class in the PrepareMapping method will result in an InvalidOperationException. If you create more than one mapping configuration for the same class in the PrepareMapping method, Telerik Data Access will throw an InvalidOperationException during runtime.
Setting DataAccessKind
You could specify the DataAccessKind for the entity by using the WithDataAccessKind method. The DataAccessKind specifies the type of access for the entity. It could be:
- Default - specifies that the default value for the data access kind (read/write) will be used by the runtime.
- ReadWrite - the type allows full access to the data. All CRUD modifications are allowed.
- InsertOnly - the type allows only reading and inserting operations. No modifications (update or delete) are allowed.
- ReadOnly - the type is read-only. No CUD modifications (create, update or delete) are allowed.
MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
personConfiguration.MapType(p => new
{
Id = p.Id,
FirstName = p.FirstName,
LastName = p.LastName,
HomeAddress = p.Address
}).WithDataAccessKind(Telerik.OpenAccess.DataAccessKind.ReadOnly).ToTable("People");
Dim personConfiguration As New MappingConfiguration(Of Person)()
personConfiguration.MapType(Function(p) New With {Key .Id = p.Id,
Key .FirstName = p.FirstName,
Key .LastName = p.LastName,
Key .HomeAddress = p.Address}). _
WithDataAccessKind(Telerik.OpenAccess.DataAccessKind.ReadOnly).ToTable("People")
Setting ConcurencyControl and Version Member
You could specify the ConcurencyControl for the class, by using the WithConcurencyControl method. The version member could be specified by using the HasVersion method of the MappingConfiguration object. The HasVersion method specifies that the class will use an internal member for version control. The method returns a property configuration object that allows you to make an additional configuration for the internal version member. For example, you could specify the name of the column that the version member is mapped to. Usually the data type for the version column is int, and the version number is incremented on every update.
MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
personConfiguration.MapType(p => new
{
Id = p.Id,
FirstName = p.FirstName,
LastName = p.LastName,
HomeAddress = p.Address
}).WithConcurencyControl(Telerik.OpenAccess.OptimisticConcurrencyControlStrategy.Version).ToTable("People");
personConfiguration.HasVersion().ToColumn("VersionColumn");
Dim personConfiguration As New MappingConfiguration(Of Person)()
personConfiguration.MapType(Function(p) New With {Key .Id = p.Id,
Key .FirstName = p.FirstName,
Key .LastName = p.LastName,
Key .HomeAddress = p.Address}). _
WithConcurencyControl(Telerik.OpenAccess.OptimisticConcurrencyControlStrategy.Version). _
ToTable("People")
personConfiguration.HasVersion().ToColumn("VersionColumn")
Setting CacheStrategy
You could specify the CacheStrategy for the persistent, by using the WithCacheStrategy method.
MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
personConfiguration.MapType(p => new
{
Id = p.Id,
FirstName = p.FirstName,
LastName = p.LastName,
HomeAddress = p.Address
}).WithCacheStrategy(Telerik.OpenAccess.Metadata.CacheStrategy.Yes).ToTable("People");
Dim personConfiguration As New MappingConfiguration(Of Person)()
personConfiguration.MapType(Function(p) New With {Key .Id = p.Id,
Key .FirstName = p.FirstName,
Key .LastName = p.LastName,
Key .HomeAddress = p.Address}). _
WithCacheStrategy(Telerik.OpenAccess.Metadata.CacheStrategy.Yes).ToTable("People")
Use the ToColumn Method
Another way to configure explicit mapping is to use the ToColumn method. Consider the following example. Only two properties from the Person class are mapped by using explicit mapping. At this point there is no mapping configured for the LastName and Address properties. These properties will not be added to the metadata container, and respectively no relational parts will be created for them.
MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>();
personConfiguration.MapType( p => new
{
Id = p.Id,
FirstName = p.FirstName,
} ).ToTable( "People" );
Dim personConfiguration As New MappingConfiguration(Of Person)()
personConfiguration.MapType(Function(p) New With {Key .Id = p.Id,
Key .FirstName = p.FirstName}).ToTable("People")
personConfiguration.FieldNamingRules.AddPrefix = "_"
At later stage, you can explicitly map the LastName and Address properties in the following manner:
personConfiguration.HasProperty(p => p.LastName).ToColumn("Last_Name");
personConfiguration.HasProperty(p => p.Address).ToColumn("Address");
personConfiguration.HasProperty(Function(p) p.LastName).ToColumn("Last_Name")
personConfiguration.HasProperty(Function(p) p.Address).ToColumn("Address")
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
Sample FluentMetadataSource Implementation - Mapping CLR Types
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
{
Id = p.Id,
FirstName = p.FirstName,
LastName = p.LastName,
HomeAddress = p.Address
}).
WithDataAccessKind(Telerik.OpenAccess.DataAccessKind.ReadOnly).
WithCacheStrategy(CacheStrategy.Yes).
WithConcurencyControl(Telerik.OpenAccess.OptimisticConcurrencyControlStrategy.Version).
ToTable("People");
personConfiguration.HasProperty( p => p.Id ).IsIdentity( KeyGenerator.Autoinc );
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 .Id = p.Id,
Key .FirstName = p.FirstName,
Key .LastName = p.LastName,
Key .HomeAddress = p.Address}).
WithCacheStrategy(CacheStrategy.Yes).
WithDataAccessKind(Telerik.OpenAccess.DataAccessKind.ReadOnly).
WithConcurencyControl(Telerik.OpenAccess.OptimisticConcurrencyControlStrategy.Version).
ToTable("People")
personConfiguration.HasProperty(Function(p) p.Id).IsIdentity(KeyGenerator.Autoinc)
personConfiguration.FieldNamingRules.AddPrefix = "_"
configurations.Add(personConfiguration)
Return configurations
End Function
End Class