Using Complex Types in Entity Framework
Recently a participant of my ASP.NET MVC training program asked me about
complex types in entity framework. This article attempts to answer that
A database table represents your application data in row-column format.
Although in many cases this row-column structure can be mapped directly to
entities, at times you may need to reorganize the same. Consider, for example,
the Customers table of Northwind database. The Customers table has Address,
City, Region, Country and PostalCode columns representing the address of the
company. The entity that represents this table might not be as "flat" as the
table. For example, you may wish to have a property - Location - that is of
class type and has properties such as Street, City, Region and PostalCode.
Luckily, entity framework allows you to do so quite easily. The remainder of
this article explains how.
Consider the following entity that maps with a row of the Customers table.
The Customer entity shown above is generated as the result of "Generate from
database" wizard. As you can see the Customer class has five properties that
represent location of a customer - Address, City, Region, Country and PostalCode.
To access these properties you will need to write code as shown in the following
NorthwindEntities db=new NorthwindEntities();
var query = from c in db.Customers
where c.CustomerID == "ALFKI"
Customer obj = query.SingleOrDefault();
string street = obj.Address;
string city = obj.City;
// access other location properties here
This is quite straightforward code and needs no explanation.
Now suppose that you wish to isolate location information into a separate
class named Address. To do so there are two ways:
- Refactor existing properties into a new class
- Map an existing class with a property
In both of the above techniques, the Customer class needs to have a property
of complex type i.e. a property that is of a class type. Unlike its current form
where all the properties of the Customer class are scalar properties (string,
int etc.) the modified Customer class will have a property named, say, Location
that is of type CompanyAddress. Let's see how this can be accomplished with both
of the techniques listed above.
Refactoring properties into a new complex type
The simplest way to accomplish our goal is to use some inbuilt menu option.
Select all the five properties of the Customer entity in the Visual Studio
designer and right click on them to reveal Refactor menu. The following figure
shows how this is done.
When you click on the "Move to New Complex Type" menu option, the selected
properties are isolated into a new complex type. You can see this newly created
complex type in the model browser (see below).
You can change the name of the complex type in the model browser by pressing
F2 and then entering the new name. You will find that the Customer class now has
a property named ComplexProperty that is of type CompanyAddress. You can rename
this property to, say, Location. The following figure shows the Customer class
after making this change.
Once you create the Location property you can access it in your code like
Of course, if you wish you can also rename the properties of the
CompanyAddress complex type create in the process (for example, you may rename
Address property to Street).
Mapping an existing complex type with a property
In the above example a new complex type was created as a result of the
refactoring process. You can also map an existing complex type to a property.
Let's see how. Open the Model Browser, right click on the Complex Types node and
add a new complex type. Name the complex type as LocationInfo. Then right click
on the LocationInfo complex type and add five Scalar properties of type string
using Add > Scalar Property menu option.
The following figure shows the LocationInfo complex type after adding all the
Currently the LocationInfo complex type is no way related to the Customer
entity. The next step is to map a property of Customer to LocationInfo.
Select Location property of the Customer entity (you created this property in
the preceding example) and using Properties window change its Type property from
CompanyAddress to LocationInfo. You could have also added a fresh property and
map it to LocationInfo.
Then, right click on the Customer entity and select Table Mapping menu option
to reveal the table-property mapping. Then map Address, City, Region, Country
and PostalCode columns of Customers table to LocationInfo.Street,
LocationInfo.City, LocationInfo.Region, LocationInfo.Country and
LocationInfo.PostalCode properties respectively. The following figure shows this
Once done you can now use the newly mapped property like this:
That's it for this article! Keep coding !!