gpt4 book ai didi

c# - 如何定义与 ValueObjects 的嵌套模型关系

转载 作者:行者123 更新时间:2023-11-30 16:37:37 26 4
gpt4 key购买 nike

我有一个父子关系,其中父项有一个 ValueObject,我无法确定如何正确定义该关系。

为子/父关系添加迁移失败并出现错误...

实体类型“地址”需要定义主键。

以下是当前的代码结构。

public class Address
{
[Required]
public string BuildingNumber { get; private set; }

// other address properties...
}
public class Parent
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }

[Required]
public Address PrimaryAddress { get; private set; }
}
public class ParentContext : DbContext
{
public ParentContext(DbContextOptions<ParentContext> options) :
base(options)
{
}

public DbSet<Parent> Parents { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Parent>().OwnsOne(p => p.PrimaryAddress);

// Flatten the ValueObject fields into table
modelBuilder.Entity<Parent>().OwnsOne(p => p.PrimaryAddress).
Property(b => b.BuildingNumber).IsRequired().
HasColumnName("Primary_BuildingName");
}
}
public class Child
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }

[Required]
public int ParentId { get; private set; }

[ForeignKey("ParentId")]
public Parent Parent { get; private set; }
}
public class ChildContext : DbContext
{
public ChildContext(DbContextOptions<ChildContext> options) : base(options)
{
}

public DbSet<Child> Children { get; set; }
}

使用上面的代码示例,我可以运行单独的命令来为父项和子项创建迁移,并且表格看起来是正确的。

add-migration create-parent -c parentcontext

add-migration create-child -c childcontext

将关系添加到实体并添加最终迁移失败。

add-migration add-parent-child-fk -c childcontext

问题只发生在我的 child 和 parent 处于不同的上下文中时。

我已尝试在父子关系中以不同方式定义关系以映射地址字段,以便 child “理解”映射,但我尝试过的任何事情都无法避免 EF 错误。

示例项目在这里

https://github.com/cimatt55/ef-parent-valueobject

最佳答案

主要问题是单独的上下文。值对象(拥有的实体类型)只是一个结果 - 如果没有值对象,那么您将遇到其他问题。

您的设计似乎基于错误的假设,即只有公开公开的 DbSet 中的实体类。但事实并非如此。还包括导航属性引用的实体,以及它们引用的实体等。

这是合乎逻辑的,因为 EF Core 上下文表示具有表和关系的数据库。 EF Core 需要知道所有相关实体才能正确支持加载相关数据、查询(连接)、级联删除、表、列、主键和外键属性/列及其映射等。

这在 Including & Excluding Types 中有解释EF Core 文档部分:

By convention, types that are exposed in DbSet properties on your context are included in your model. In addition, types that are mentioned in the OnModelCreating method are also included. Finally, any types that are found by recursively exploring the navigation properties of discovered types are also included in the model.

为您的 ChildContext 调整他们的示例,发现以下类型:

  • Child 因为它在上下文的 DbSet 属性中公开
  • Parent 因为它是通过 Child.Parent 导航属性发现的
  • Address 因为它是通过 Parent.PrimaryAddress 导航属性发现的

由于 ChildContext 没有 Parent 实体配置,因此 EF 假定与 Parent(和 Address)相关的所有内容以按照惯例,因此异常(exception)。

简而言之,使用包含相关实体的单独上下文不是一个好主意。解决方案是将所有相关实体放在一个上下文中并进行维护。

看看所使用的术语,您可能会关注 DDD 和限界上下文,但这些不适合 EF Core(通常在关系数据库)模型中。

关于c# - 如何定义与 ValueObjects 的嵌套模型关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57563527/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com