我遇到类似以下玩具示例的情况:
public class Person
{
public Guid Id { get; set; }
public string FullName { get; set; }
public ContactInfo ContactInfo { get; set; }
}
public class ContactInfo
{
public string EmailAddress { get; set; }
public IEnumerable<Address> PostalAddresses { get; set; }
}
public class Address
{
public Guid Id { get; set; }
public Guid PersonId { get; set; }
/* ... other properties ... */
}
实际情况要复杂得多,我真的希望将
PostalAddresses
属性的等价物放在ContactInfo
而不是Person
上。
使用实体框架代码优先可以实现这一点吗?
编辑
基本上,我希望将上面的内容序列化为以下表结构:
表:人物
表:地址
所以问题是我需要将
IEnumerable<Address>
集合放在 ContactInfo
复杂类型上,而不是根类型 Person
上。当我保存 Person
对象时,不会将任何 Address
行添加到数据库中。
你的问题看起来很清楚。
我不是专家,但是根据如何在复杂类型上指定关系?你想要做的事情是不可能的。 ComplexType 不能具有导航属性。
我想解决方法是将 ContactInfo 定义为实体,而不是复杂类型。所以 ContactInfo 将有一个 PK 和它自己的表。
也许其他人知道更好的解决方案?
顺便说一句,我尝试做类似的事情。我的(简化)域名:
申请
简历
经验
培训
候选人
我最终也给了简历一个 Id,但结果是一个冗余的 Review 表,仅包含一列,即简历 Id(等于应用程序 Id)。
好问题。
但是复杂类型的存在可以让代码变得更简单、更快,因为它们减少了查询中的关系,从而提高了查询性能并简化了关系。
如果我们有一个名为 Author 的类,另一个名为 Book 的类 我们已经将复杂类型实现为 Microsoft 文档,然后我们创建新的迁移,我们会发现该表将如下所示
migrationBuilder.CreateTable(
name: "Books",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
Published = table.Column<DateTime>(type: "datetime2", nullable: false),
ISBN = table.Column<string>(type: "nvarchar(max)", nullable: false),
Author_Country = table.Column<string>(type: "nvarchar(max)", nullable: false),
Author_FirstName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Author_LastName = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Books", x => x.Id);
});
如上所示,复杂类型可以通过将相关属性直接嵌入到父表中来简化数据库架构,而不是为相关实体创建单独的表。
但是,当您不需要单独查询相关数据时,复杂类型可以很好地工作。对于一对多关系,您需要一个单独的表来处理导航属性并保持数据一致。