EFCore 具有单一导航属性的一对多关系

问题描述 投票:0回答:1

我遇到了一个奇怪的情况,想知道你是否可以帮助我。

我有包含一对多关系的实体。在父实体上,我不想添加作为子实体列表的导航属性。相反,我希望它包含子实体的单个实例。查询时,我将通过其中一列来约束子实体。

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

    /// This is the normal behavior, when EFCore discovers this by convention it will
    /// create a one-to-many relationship as expected
    /// public List<Child> Children { get; set;}

    /// This is my desired usage, but when the relationship is built it generates
    /// a one to one and restricts creating multiple children with the same parent id.
    public Child { get; set;}
}

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

我尝试手动创建关系,但查询连接到了错误的列。

c# entity-framework-core
1个回答
0
投票

这要么成为一对一的关系,要么成为多对一的关系,其中一个孩子可以被许多父母参考。

假设一对一关系,EF 的默认行为和正常的标准化关系是通过 PK 连接两行。例如,采用与 CustomerDetails 表具有一对一关系的 Customer 表。这两个表都将使用 CustomerId 作为其 PK,并且客户配置为

HasOne(c => c.CustomerDetail)
.WithOne()
的关系,默认的 FK EF 选择的是 CustomerDetail 上的 PK。

如果您创建 CustomerDetail 以具有 CustomerDetailId 和 CustomerId,其中 CustomerDetailId 是 PK,EF 将使用它,除非您明确告诉它使用 CustomerId。这将使用

.HasForeignKey(cd => cd.CustomerId)
.HasForeignKey("CustomerId")
或者如果 CustomerDetail 不公开 CustomerId 属性。如果 FK 在 Customer (CustomerDetailId) 上,那么您需要
.HasForeignKey<Customer>("CustomerDetailId")
告诉 EF 在 Customer 端查找 FK。

在双向引用的情况下,另一侧有 CustomerDetail.Customer 并使用

.WithOne(cd => cd.Customer)
,那么 EF 应该 自动将相关 FK 结合起来。

使用这种形式的一对一关系时,请务必在 Parent.ChildId 或 Child.ParentId(无论您放置显式 FK 的哪一侧)上配置唯一索引。在代码优先中,这应该将实体关系配置为

IsUnique()
,或者向实体添加
[Index(nameof(ChildId), IsUnique=true)]
属性。如果没有唯一约束,它是一种多对一关系,其中多个父项可以通过具有相同子项 ID 的重复记录来引用同一个子项。 (或具有相同父 ID 的重复子项)

© www.soinside.com 2019 - 2024. All rights reserved.