How to: Define a Model with Complex Type (Entity Framework)

The complex type in the Entity Data Model (EDM) is a data type with internal structure but without a key property. The complex type is used to implement a property that has internal properties of its own. Either an entity or a complex type can have a property declared as complex type.

A complex type is declared in syntax similar to an entity type. The main difference is that a complex type does not include the declaration of a key property as in an entity. In the mapping specification, a complex type is mapped as a complex property.

To implement a complex property

  1. Create a project in Visual Studio of the class library type and add references to System.Data.Entity and System.Runtime.Serialization.

  2. Add a new Entity Data Model template to the project.

  3. Implement the conceptual schema design language (CSDL) schema and add it to the CSDL file provided by the EDM template. The schema includes declarations of the CCustomer entity and its Address property that uses the complex type CAddress. The complete schema is shown in the example code below.

  4. Run edmgen.exe on the conceptual schema created in step 2 to create the object code.

  5. Implement the store schema definition language (SSDL) schema and add it to the SSDL file provided by the EDM template. In this schema the complex type data is stored in the same table as the containing entity as shown in the following store schema design language (SSDL) metadata. The complete schema is shown in the example code below.

  6. Implement the mapping specification language (MSL) schema and add it to the MSL file provided by the EDM template. The following mapping schema shows the mapping of Address as a complex property. The complete mapping specification is shown in the example code below.

Example

The three required schemas are shown consecutively in the following XML. Following the code, a script is supplied that can be used to create the database used for storage in this example.

    <Schema Namespace="CustomerComplexAddress"
        Alias="Self"
        xmlns="https://schemas.microsoft.com/ado/2006/04/edm">

        <EntityContainer Name="CustomerComplexAddressContext">
          <EntitySet Name="CCustomers" EntityType="CustomerComplexAddress.CCustomer" />
        </EntityContainer>

        <EntityType Name="CCustomer">
          <Key>
            <PropertyRef Name="CustomerId" />
          </Key>
          <Property Name="CustomerId" Type="Int32" Nullable="false" />
          <Property Name="CompanyName" Type="String" />
          <Property Name="ContactName" Type="String" />
          <Property Name="ContactTitle" Type="String" />
          <Property Name="Address" Type="Self.CAddress" Nullable="false" />
        </EntityType>

        <ComplexType Name="CAddress">
          <Property Name="StreetAddress" Type="String" />
          <Property Name="City" Type="String" />
          <Property Name="Region" Type="String" />
          <Property Name="PostalCode" Type="String" />
          <Property Name="Country" Type="String" />
          <Property Name="Phone" Type="String" />
          <Property Name="Fax" Type="String" />
        </ComplexType>
    </Schema>

    <Schema Namespace="CustomerComplexAddress.Store"
        Alias="Self" Provider="System.Data.SqlClient"
        ProviderManifestToken="2005"
        xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">

        <EntityContainer Name="dbo">
          <EntitySet Name="SCustomer" EntityType="CustomerComplexAddress.Store.SCustomer" />
        </EntityContainer>

        <EntityType Name="SCustomer">
          <Key>
            <PropertyRef Name="CustomerId" />
          </Key>
          <Property Name="CustomerId" Type="int" Nullable="false" />
          <Property Name="CompanyName" Type="nvarchar" MaxLength="50" />
          <Property Name="ContactName" Type="nvarchar" MaxLength="50" />
          <Property Name="ContactTitle" Type="nvarchar" MaxLength="50" />
          <Property Name="Address" Type="nvarchar" MaxLength="50" />
          <Property Name="City" Type="nvarchar" MaxLength="50" />
          <Property Name="Region" Type="nvarchar" MaxLength="50" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="50" />
          <Property Name="Country" Type="nvarchar" MaxLength="50" />
          <Property Name="Phone" Type="nvarchar" MaxLength="50" />
          <Property Name="Fax" Type="nvarchar" MaxLength="50" />
        </EntityType>
    </Schema>

    <Mapping Space="C-S"
        xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">

        <EntityContainerMapping StorageEntityContainer="dbo"
                  CdmEntityContainer="CustomerComplexAddressContext">

          <EntitySetMapping Name="CCustomers">
            <EntityTypeMapping
                 TypeName="CustomerComplexAddress.CCustomer">
              <MappingFragment StoreEntitySet="SCustomer">
                <ScalarProperty Name="CustomerId"
                                  ColumnName="CustomerId" />
                <ScalarProperty Name="CompanyName"
                                  ColumnName="CompanyName" />
                <ScalarProperty Name="ContactName"
                                  ColumnName="ContactName" />
                <ScalarProperty Name="ContactTitle"
                                  ColumnName="ContactTitle" />
               <ComplexProperty Name="Address"
                       TypeName="CustomerComplexAddress.CAddress">
                 <ScalarProperty Name="StreetAddress"
                                  ColumnName="Address" />
                 <ScalarProperty Name="City" ColumnName="City" />
                 <ScalarProperty Name="Region" ColumnName="Region" />
                 <ScalarProperty Name="PostalCode"
                                  ColumnName="PostalCode" />
                 <ScalarProperty Name="Country" ColumnName="Country" />
                 <ScalarProperty Name="Phone" ColumnName="Phone" />
                 <ScalarProperty Name="Fax" ColumnName="Fax" />
                </ComplexProperty>
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
       </EntityContainerMapping>
    </Mapping>


The following script can be used to create
    SQL Server storage model.

USE [master]
GO

CREATE DATABASE [CustomerComplexAddress] 
GO

USE [CustomerComplexAddress]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N'[dbo].[SCustomer]') 
AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[SCustomer](
    [CustomerId] [int] NOT NULL,
     [CompanyName] [nvarchar](50) NULL,
     [ContactName] [nvarchar](50) NULL,
     [ContactTitle] [nvarchar](50) NULL,
    [Address] [nvarchar](50) NULL,
     [City] [nvarchar](50) NULL,
     [Region] [nvarchar](50) NULL,
     [PostalCode] [nvarchar](50) NULL,
     [Country] [nvarchar](50) NULL,
     [Phone] [nvarchar](50) NULL,
     [Fax] [nvarchar](50) NULL,
CONSTRAINT [PK_SCustomer] PRIMARY KEY CLUSTERED 
(
     [CustomerId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
   IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, 
   ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO

See Also

Tasks

How to: Create and Execute Object Queries with Complex Types (Entity Framework)
How to: Add and Modify Objects with Complex Types (Entity Framework)

Concepts

Complex Type (EDM)