如何在 Entity Framework Core 中设置多个 one-to-one 关系?

How to set up multiple one-to-one relationships in Entity Framework Core?

我有两个实体 ParentChild;每个 parent 最多可以有两个 child 引用。我已按如下方式设置我的实体:

class Parent
{
    [Key]
    public int ParentId { get; set; }

    public int PrimaryChildId{ get; set; }
    public Child PrimaryChild { get; set; }

    public int SecondaryChildId { get; set; }
    public Child? SecondaryChild { get; set; }
    // remaining properties
}

class Child 
{
    [Key]
    public int ChildId { get; set; }

    public int ParentId { get; set; }
    public Parent Parent {get; set; }

    // remaining child properties 
}

DbContext.OnModelCreating 我有这个代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>(builder =>
    {
        builder.HasOne(p => p.PrimaryChild);
        builder.HasOne(p => p.SecondaryChild);
    });
}

这还不足以实现我在这里想要实现的目标。我得到一个错误:

Unable to determine the relationship represented by navigation property 'Child.Parent' of type 'Parent'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'

我尝试从 Child 实体建立关系,但我得到了不同的错误,因为这让我为同一个 属性 建立了两个关系。我不想在我的 child 上有两个导航属性,因为我知道一次只能使用一个导航属性,因为这会导致模型混乱。

我在互联网上搜索了一下,但没有找到以这种方式建立的关系。

过去几天我一直在尝试类似的方法,在尝试了各种数据注释和 Fluent API 废话之后,我能想出的最干净的解决方案竟然非常简单这两者都不需要。它只需要将 'private' 构造函数添加到注入 'DbContext' 对象的父对象 class (如果您使用延迟加载,则添加 'protected' 构造函数)。只需将 'Parent' 和 'Child' classes 设置为正常的一对多关系,并且现在可以从 'Parent' 实体中获得数据库上下文,您可以使用 Find() 方法使 'PrimaryChild' 和 'SecondaryChild' 简单地 return 从数据库中查询。 Find() 方法也使用缓存,因此如果您多次调用 getter,它只会访问数据库一次。

这是关于此能力的文档:https://docs.microsoft.com/en-us/ef/core/modeling/constructors#injecting-services

注意:'PrimaryChild' 和 'SecondaryChild' 属性是只读的。要修改它们,请设置 'PrimaryChildId' 和 'SecondaryChildId' 属性。

class Parent
{
    public Parent() { }
    private MyDbContext Context { get; set; }
    // make the following constructor 'protected' if you're using Lazy Loading
    private Parent(MyDbContext Context) { this.Context = Context; }

    [Key]
    public int ParentId { get; set; }
    public int PrimaryChildId { get; set; }
    public Child PrimaryChild { get { return Context.Children.Find(PrimaryChildId); } }
    public int? SecondaryChildId { get; set; }
    public Child SecondaryChild { get { return Context.Children.Find(SecondaryChildId); } }
    // remaining properties
}

class Child
{
    [Key]
    public int ChildId { get; set; }
    public int ParentId { get; set; }
    public Parent Parent { get; set; }
    // remaining child properties 
}