EF 6:映射复杂类型集合?

时间:2015-04-26 14:34:16

标签: c# entity-framework domain-driven-design complextype value-objects

EF 6(代码优先)是否支持复杂类型集合(值对象集合)映射?我知道它支持复杂类型,但还没有找到一个我们有一组复杂类型的例子。

例如,假设您有一个名为Student的实体,该实体具有一组联系人。对于NH,我可以简单地说学生有一组联系人,而联系人是一个组件(相当于ef中的复杂类型)。这可以通过EF完成而不改变与实体的联系吗?

2 个答案:

答案 0 :(得分:3)

通过为复杂类型中的每个属性添加一列,将复杂类型映射到实体表。因此,将Contact作为一个单独的实体:

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;}
}

将生成具有列的Student表的映射:

ID
PrimaryContact_Address
PrimaryContact_PhoneNumber
PrimaryContact_Email
SecondaryContact_Address
SecondaryContact_PhoneNumber
SecondaryContact_Email

复杂类型只是在任何需要的地方声明相同成员的简写。您可以在需要联系人数据的一堆其他实体中使用相同的联系人类型,而无需为每个实体明确定义AddressPhoneNumberEmail属性。因此,您无法在集合中真正使用它们,因为每次要添加或删除项目时,您都必须在表格中添加或删除列。

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?

联系人项目实际上可以存储在哪里?你怎么能索引它?如果您尝试这样做,映射器将完全忽略Contacts属性。

只需从Contact类中删除ComplexType,即可干净地使用集合。不过,这会在数据库中创建一个表:

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;}
}

答案 1 :(得分:1)

显然,NHibernate在这方面更为灵活,因为在撰写本文时(EF6.2和EF Core 2.1),EF6和EF Core均不支持复杂(或更一般地,原始或值对象)类型集合映射。

EF核心甚至更糟,因为据推测是Owned Entity Types的EF复杂类型的替代品确实具有更多类似行为的实体(从更改跟踪的角度来看),因此不能说DDD不可变的多属性有价值的对象。

我知道的唯一解决方法是将某种序列化格式(例如XML,JSON,二进制等)的值对象/集合表示映射到单个数据库字符串/二进制列。这对于读取/存储数据,它缺乏查询功能,因此IMO不是一个严肃的选择。

说到EF6,我认为它永远不会得到这种支持。 EF6基本处于维护模式和won't get future major improvements

在这方面,

EF Core看起来更有希望,因为对拥有实体的集合的支持scheduled for the next EF 2.2 release。但是,尚不清楚它们将如何(最初)实现它们,并考​​虑到它们如何实现拥有的类型,这可能不是您期望的方式,因此如果它们被事先告知,适用于价值对象收集方案。

我知道这不是您想要的答案,但这是事实。

相关问题