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 question...

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 fragment:

NorthwindEntities db=new NorthwindEntities();
var query = from c in db.Customers
            where c.CustomerID == "ALFKI"
            select c;
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 this:

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 five properties:

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 mapping.

Once done you can now use the newly mapped property like this:

That's it for this article! Keep coding !!


Bipin Joshi is an independent software consultant and trainer by profession specializing in Microsoft web development technologies. Having embraced the Yoga way of life he is also a meditation teacher and spiritual guide to his students. He is a prolific author and writes regularly about software development and yoga on his websites. He is programming, meditating, writing, and teaching for over 27 years. To know more about his ASP.NET online courses go here. More details about his Kriya and Meditation online course are available here.

Posted On : 15 January 2014

Tags : ADO.NET Data Access Visual Studio