Array and IList<ValueT> Property Mapping
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 topic will show you how to map array and IList properties. The Fluent Mapping API exposes the following extension methods for array and IList property configuration:
- WithValueColumn(string columnName) - allows you to specify the name of the table column which will hold the array or IList collection values.
- WithValueOpenAccessType(OpenAccessType openAccessType) - allows you to specify the OpenAccessType of the column holding the array or IList collection values. With this method you can set the column type independently from the actual database engine.
- HasValueColumnType(string columnSQLType) - allows you to specify the SQL type of the column holding the array or IList collection values. Note that the value passed to this method depends on the used database engine.
- HasValuePrecision(int precision) - allows you to set the precision of the column holding the array or IList collection values.
- HasValueScale(int scale) - allows you to set the scale of the column holding the array or IList collection values.
- HasValueLength(int length) - allows you to set the length of the column holding the array or IList collection values.
- WithSequenceColumn(string columnName) - allows you to specify the name of the sequence column which will hold the array or IList indexes.
- WithSequenceColumnOpenAccessType(OpenAccessType openAccessType) - allows you to specify the OpenAccessType of the sequence column. With this method you can set the column type independently from the actual database engine.
- HasSequenceColumnType(string columnType) - allows you to specify the SQL type of the sequence column. The value passed to this method depends on the used database engine.
- HasSequenceColumnPrecision(int precision) - allows you to set the precision of the sequence column.
- HasSequenceColumnScale(int scale) - allows you to specify the scale of the sequence column.
- WithForeignKey - specifies the foreign key column of the table to which the array or IList property is mapped.
- WithTable - specifies the name of the table to which the array or IList property is mapped.
The source type of the array and the IList should be a primitive CLR type.
The extension methods for configuring of array and IList properties are located in the Telerik.OpenAccess.Metadata.Fluent and Telerik.OpenAccess.Metadata.Fluent.Advanced namespaces.
Mapping an Array Property
The values of array and IList properties are stored in separate tables. These tables are in relation with the table mapped to the class which contains the said properties. The pattern for mapping array and IList properties is the same. Its basic form consists of the following steps:
- Specify the column which will hold the array or IList collection values using the WithValueColumn method.
- Specify the OpenAccessType of the column which will hold the array or IList collection values using the WithValueOpenAccessType method.
- Specify the sequence column using the WithSequenceColumn method. The sequence column will hold the array indexes of the array or IList collection values.
- Specify the OpenAccessType of the sequence column using the WithSequenceColumnOpenAccessType method.
- Specify the foreign key of the array/IList table using the WithForeignKey method.
- Specify the name of the array/IList table using the WithTable method.
Here is a sample implementation of the FluentMetadataSource PrepareMapping method demonstrating how to map the Customer class that contains an array and IList properties.
protected override IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> configurations = new List<MappingConfiguration>();
MappingConfiguration<Customer> customerConfigurations = new MappingConfiguration<Customer>();
customerConfigurations.MapType(p => new
{
Id = p.Id,
CustomerName = p.Name
}).ToTable("Customers");
customerConfigurations.HasProperty(c => c.Id).IsIdentity(KeyGenerator.Autoinc);
//mapping array property
customerConfigurations.HasProperty(customer => customer.OrderDates)
.WithValueColumn("ArrayValue")
.WithValueOpenAccessType(OpenAccessType.DateTime)
.WithSequenceColumn("SequenceId")
.WithSequenceColumnOpenAccessType(OpenAccessType.Int32)
.WithForeignKey("CustomerId")
.WithTable("Customer_Orders");
//mapping IList property
customerConfigurations.HasProperty(customer => customer.Addresses)
.WithValueColumn("ListValue")
.WithValueOpenAccessType(OpenAccessType.StringInfiniteLength)
.WithSequenceColumn("SequenceId")
.WithSequenceColumnOpenAccessType(OpenAccessType.Int32)
.WithForeignKey("CustomerId")
.WithTable("Customer_Addresses");
configurations.Add(customerConfigurations);
return configurations;
}
Protected Overrides Function PrepareMapping() As IList(Of MappingConfiguration)
Dim configurations As New List(Of MappingConfiguration)()
Dim customerConfigurations As New MappingConfiguration(Of Customer)()
customerConfigurations.FieldNamingRules.AddPrefix = "_"
customerConfigurations.MapType(Function(p) New With { _
Key .Id = p.Id, _
Key .CustomerName = p.Name _
}).ToTable("Customers")
customerConfigurations.HasProperty(Function(c) c.Id).IsIdentity(KeyGenerator.Autoinc)
'mapping array property
customerConfigurations.HasProperty(Of DateTime)(Function(customer) customer.OrderDates).
WithValueColumn("ArrayValue").
WithValueOpenAccessType(OpenAccessType.DateTime).
WithSequenceColumn("SequenceId").
WithSequenceColumnOpenAccessType(OpenAccessType.Int32).
WithForeignKey("CustomerId").
WithTable("Customer_Orders")
'mapping IList property
customerConfigurations.HasProperty(Of String)(Function(customer) customer.Addresses).
WithValueColumn("ListValue").
WithValueOpenAccessType(OpenAccessType.StringInfiniteLength).
WithSequenceColumn("SequenceId").
WithSequenceColumnOpenAccessType(OpenAccessType.Int32).
WithForeignKey("CustomerId").
WithTable("Customer_Addresses")
configurations.Add(customerConfigurations)
Return configurations
End Function
After creating the database, the database schema should look like the snapshot below:
Customer Class
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime[] OrderDates { get; set; }
public IList<string> Addresses { get; set; }
}
Public Class Customer
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 _name As String
Public Property Name As String
Get
Return _name
End Get
Set(value As String)
_name = value
End Set
End Property
Private _orderDates As Date()
Public Property OrderDates As Date()
Get
Return _orderDates
End Get
Set(value As Date())
_orderDates = value
End Set
End Property
Private _addresses As IList(Of String)
Public Property Addresses As IList(Of String)
Get
Return Me._addresses
End Get
Set(value As IList(Of String))
Me._addresses = value
End Set
End Property
End Class