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

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