Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF 6: mapping complex type collection?

Does EF 6 (code first) supports complex type collection(Value Object collections) mappings? I know that it supports Complex types, but haven't still found an example where we have a collection of complex types.

For instance, suppose you have an entity called Student, which has a collection of contacts. With NH, I can simply say that Student has a collection of contacts and that contact is a component (equivalent to complex type in ef). Can this be done with EF without changing contact to an entity?

like image 530
Luis Abreu Avatar asked Apr 26 '15 14:04

Luis Abreu


People also ask

What is complex type in EF?

What is a Complex Type. Complex types are non-scalar properties of entity types that enable scalar properties to be organized within entities. Like entities, complex types consist of scalar properties or other complex type properties.

What is mapping in EF?

It is a tool to access the database. More accurately, it's classified as an Object/Relational Mapper (ORM) which means it maps the data in a relational database into objects of our applications.

What is complex type in C#?

A complex type is a set of properties that exist in its own object for C#, but are mapped to columns on an already existing table (the one for the entity that contains it), instead of having its own table (which would need a key, etc.).


1 Answers

Complex types are mapped to the entity's table by just adding a column for each property in the complex type. So, with Contact as a separate entity:

public class Student
{
    [Key]
    public int ID {get; set;}
    public Contact PrimaryContact { get; set; }
    public Contact SecondaryContact{ get; set; }
}

[ComplexType]
public class Contact
{
    public string Address{get; set;}
    public string PhoneNumber{get; set;}
    public string Email{get; set;}
}

Will yield a mapping of a Student table that has columns:

ID
PrimaryContact_Address
PrimaryContact_PhoneNumber
PrimaryContact_Email
SecondaryContact_Address
SecondaryContact_PhoneNumber
SecondaryContact_Email

Complex types are just shorthand for declaring the same members wherever you need it. You could use that same Contact type in a bunch of other entities that need contact data without having to explicitly define Address, PhoneNumber, and Email properties for each entity. So you can't really use them in a collection, because every time you wanted to add or remove items to it, you'd have to add or remove columns from the table itself.

public class Student
{
    [Key]
    public int ID {get; set;}
    public ICollection<Contact> Contacts{ get; set; }
}

[ComplexType]
public class Contact
{
    public string Address{get; set;}
    public string PhoneNumber{get; set;}
    public string Email{get; set;}
}

ID
Contacts[x]_Address?
Contacts[x]_PhoneNumber?
Contacts[x]_Email?

Where could Contacts items actually be stored? How could you index it? If you try to do this, the mapper would just ignore the Contacts property altogether.

You can cleanly use collections by just removing the ComplexType from the Contact class. This would create a table in the database, though:

public class Student
{
    [Key]
    public int ID {get; set;}
    public ICollection<Contact> Contacts{ get; set; }
}

public class Contact
{
    [Key]
    public int ID {get; set;}
    public string Address{get; set;}
    public string PhoneNumber{get; set;}
    public string Email{get; set;}
}
like image 97
AMG Avatar answered Sep 30 '22 06:09

AMG