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.
C#csharp | Copy Code |
---|---|
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; } } |
Visual Basic | Copy Code |
---|---|
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.
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.
C#csharp | Copy Code |
---|---|
[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; } } |
Visual Basic | Copy Code |
---|---|
<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 |
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>
FluentMappingBuilder class methods are used for mapping complex types.
C#csharp | Copy Code |
---|---|
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"); |
Visual Basic | Copy Code |
---|---|
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