LinqConnect Documentation
In This Topic
    Complex Type Mapping
    In This Topic

    Complex types, used as class member types, can have common mapping for all classes in the model and custom mappings for some class. Common mapping is used by all classes having properties of this type by default, however you can define custom mapping for a class, which will override the default one. Thus, one complex type class may have different mappings for each entity class.

    Let's use the following sample classes to demonstrate complex type mapping.


    public class Company {
        public int Id { get; set; }
        public AddressType Address { get; set; }
        // ...
    }
     
    public class Contact {
        public int Id { get; set; }
        public AddressType Address { get; set; }
        // ...
    }
     
    public class AddressType {
        public string Country { get; set; }
        public string City { get; set; }
        public string Street { get; set; }
        public string Zip { get; set; }
    }
    
    Public Class Company
        Public Property Id As Integer
        Public Property Address As AddressType
        '...
    End Class
    
    Public Class Contact
        Public Property Id As Integer
        Public Property Address As AddressType
        '...
    End Class
    
    Public Class AddressType
        Public Property Country As String
        Public Property City As String
        Public Property Street As String
        Public Property Zip As String
    End Class
    

    In this sample we will create common mapping for the AddressType class. The Company class will use the default common mapping of AddressType, and the Contact class will have its own specific mapping for it.

    Attribute Mapping

    When using attribute mapping, the ValueTypeProperty attribute should be specified for complex type properties. The properties of a complex type class are mapped with the Column attribute.


    [Table]
    public class Company {
     
        [Column(IsPrimaryKey=true)]
        public int Id { get; set; }
     
        [ValueTypeProperty]
        public AddressType Address { get; set; }
     
        // ...
    }
     
    [Table]
    public class Contact {
     
        [Column(IsPrimaryKey = true)]
        public int Id { get; set; }
     
        [ValueTypeProperty]
        [Column(Member="Country", Name="COUNTRY", CanBeNull=false, DbType="VARCHAR2(400) NOT NULL")]
        [Column(Member="City", Name="CITY", CanBeNull=false, DbType="VARCHAR2(400) NOT NULL")]
        [Column(Member="Street", Name="STREET", CanBeNull=false, DbType="CLOB NOT NULL")]
        [Column(Member="Zip", Name="ZIP", CanBeNull=false, DbType="VARCHAR2(400) NOT NULL")]
        public AddressType Address { get; set; }
     
        // ...
    }
     
    public class AddressType {
     
        [Column(CanBeNull=false, DbType="VARCHAR2(400) NOT NULL")]
        public string Country { get; set; }
     
        [Column(CanBeNull=false, DbType="VARCHAR2(400) NOT NULL")]
        public string City { get; set; }
     
        [Column(CanBeNull=false, DbType="VARCHAR2(400) NOT NULL")]
        public string Street { get; set; }
     
        [Column(CanBeNull=false, DbType="VARCHAR2(40) NOT NULL")]
        public string Zip { get; set; }
    }
        <Table()> _
    Public Class Company
    
        <Column(IsPrimaryKey:=True)> _
    Public Property Id As Integer
    
        <ValueTypeProperty()> _
        Public Property Address As AddressType
    
        '...
    End Class
    
    <Table()>
    Public Class Contact
    
        <Column(IsPrimaryKey:=True)> _
        Public Property Id As Integer
    
        <ValueTypeProperty()> _
        <Column(Member:="Country", Name:="COUNTRY", CanBeNull:=False, DbType:="VARCHAR2(400) NOT NULL")> _
        <Column(Member:="City", Name:="CITY", CanBeNull:=False, DbType:="VARCHAR2(400) NOT NULL")> _
        <Column(Member:="Street", Name:="STREET", CanBeNull:=False, DbType:="CLOB NOT NULL")> _
        <Column(Member:="Zip", Name:="ZIP", CanBeNull:=False, DbType:="VARCHAR2(400) NOT NULL")> _
        Public Property Address As AddressType
    
        '...
    End Class
    
    Public Class AddressType
    
        <Column(CanBeNull:=False, DbType:="VARCHAR2(400) NOT NULL")> _
        Public Property Country As String
    
        <Column(CanBeNull:=False, DbType:="VARCHAR2(400) NOT NULL")> _
        Public Property City As String
    
        <Column(CanBeNull:=False, DbType:="VARCHAR2(400) NOT NULL")> _
        Public Property Street As String
    
        <Column(CanBeNull:=False, DbType:="VARCHAR2(40) NOT NULL")> _
        Public Property Zip As String
    
    End Class
    

    XML Mapping

    Database tag is used for DataContext XML mapping. Its Name attribute defines the schema name and the Provider attribute defines the Provider.

    <Database ...>
      <Table>
        <Type Name="Company">
          <Column Member="Id" IsPrimaryKey="true" />
          <Column Member="Address" Type="AddressType" IsValueType="True" />
          ...
        </Type>
      </Table>
      <Table>
        <Type Name="Contact">
          <Column Member="Id" IsPrimaryKey="true" />
          <Column Member="Address" Type="AddressType" IsValueType="True">
            <TypeMapping>
              <Column Name="COUNTRY" Member="Country" CanBeNull="false" DbType="VARCHAR2(400) NOT NULL" />
              <Column Name="CITY" Member="City" CanBeNull="false" DbType="VARCHAR2(400) NOT NULL" />
              <Column Name="STREET" Member="Street" CanBeNull="false" DbType="CLOB NOT NULL" />
              <Column Name="ZIP" Member="Zip" CanBeNull="false" DbType="VARCHAR2(40) NOT NULL" />
            </TypeMapping>
          </Column>
          ...
        </Type>
      </Table>
      <Type Name="AddressType">
        <Column Name="Country" Member="Country" CanBeNull="false" DbType="VARCHAR2(400) NOT NULL" />
        <Column Name="City" Member="City" CanBeNull="false" DbType="VARCHAR2(400) NOT NULL" />
        <Column Name="Street" Member="Street" CanBeNull="false" DbType="VARCHAR2(400) NOT NULL" />
        <Column Name="Zip" Member="Zip" CanBeNull="false" DbType="VARCHAR2(40) NOT NULL" />
      </Type>
      ...
    </Database>

    Fluent Mapping

    FluentMappingBuilder class methods are used for mapping complex types.


    FluentMappingBuilder builder = new FluentMappingBuilder(null);
    
    // Company mapping
    builder.Entity<Company>()
        .PrimaryKey(p => p.Id);
    
    // Contact mapping
    builder.Entity<Contact>()
        .PrimaryKey(p => p.Id);
    builder.Entity<Contact>()
        .Property(p => p.Address.Country)
            .ColumnName("COUNTRY")
            .NotNullable()
            .ServerDataType("VARCHAR2(400) NOT NULL");
    builder.Entity<Contact>()
        .Property(p => p.Address.City)
            .ColumnName("CITY")
            .NotNullable()
            .ServerDataType("VARCHAR2(400) NOT NULL");
    builder.Entity<Contact>()
        .Property(p => p.Address.Street)
            .ColumnName("STREET")
            .NotNullable()
            .ServerDataType("CLOB NOT NULL");
    builder.Entity<Contact>()
        .Property(p => p.Address.Zip)
            .ColumnName("ZIP")
            .NotNullable()
            .ServerDataType("VARCHAR2(40) NOT NULL");
    
    // Complex type mapping:
    builder.ComplexType<AddressType>()
        .Property(p => p.Country)
            .NotNullable()
            .ServerDataType("VARCHAR2(400) NOT NULL");
    builder.ComplexType<AddressType>()
        .Property(p => p.City)
            .NotNullable()
            .ServerDataType("VARCHAR2(400) NOT NULL");
    builder.ComplexType<AddressType>()
        .Property(p => p.Street)
            .NotNullable()
            .ServerDataType("VARCHAR2(400) NOT NULL");
    builder.ComplexType<AddressType>()
        .Property(p => p.Zip)
            .ColumnName("Zip")
            .NotNullable()
            .ServerDataType("VARCHAR2(40) NOT NULL");
    
    Dim builder As New FluentMappingBuilder(Nothing)
     
    ' Company mapping
    builder.Entity(Of Company) _
        .PrimaryKey(Function(p) p.Id)
    
    ' Contact mapping
    builder.Entity(Of Contact)() _
        .PrimaryKey(Function(p) p.Id)
    builder.Entity(Of Contact)() _
        .Property(Function(p) p.Address.Country) _
            .ColumnName("COUNTRY") _
            .NotNullable() _
            .ServerDataType("VARCHAR2(400) NOT NULL")
    builder.Entity(Of Contact)() _
        .Property(Function(p) p.Address.City) _
            .ColumnName("CITY") _
            .NotNullable() _
            .ServerDataType("VARCHAR2(400) NOT NULL")
    builder.Entity(Of Contact)() _
        .Property(Function(p) p.Address.Street) _
            .ColumnName("STREET") _
            .NotNullable() _
            .ServerDataType("CLOB NOT NULL")
    builder.Entity(Of Contact)() _
        .Property(Function(p) p.Address.Zip) _
            .ColumnName("ZIP") _
            .NotNullable() _
            .ServerDataType("VARCHAR2(40) NOT NULL")
    
    ' Complex type mapping:
    builder.ComplexType(Of AddressType) _
        .Property(Function(p) p.Country) _
            .NotNullable() _
            .ServerDataType("VARCHAR2(400) NOT NULL")
    builder.ComplexType(Of AddressType) _
        .Property(Function(p) p.City) _
            .NotNullable() _
            .ServerDataType("VARCHAR2(400) NOT NULL")
    builder.ComplexType(Of AddressType) _
        .Property(Function(p) p.Street) _
            .NotNullable() _
            .ServerDataType("VARCHAR2(400) NOT NULL")
    builder.ComplexType(Of AddressType) _
        .Property(Function(p) p.Zip) _
            .ColumnName("Zip") _
            .NotNullable() _
            .ServerDataType("VARCHAR2(40) NOT NULL")
    End Sub
    

    For more information see the ComplexConfiguration and ComplexConfiguration<TClass> Classes