EF Core Fluent API:具有 2 种不同语法的一对一关系,只有一种有效

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

一对一关系是在 2 个实体之间以两种不同的方式定义的,但只有使用通用方法的一种有效。配置是在

DomainVerification
实体上完成的。

给出 2 个模型:

public class Domain
{
    public long Id { get; set; }
}

public class DomainVerification
{
    public long Id { get; set; }
    public Domain Domain { get; set; }
}

一种配置使用通用方法,另一种配置使用导航属性

Domain
用于配置外键。

// This works
public void Configure(EntityTypeBuilder<DomainVerification> builder)
{
    builder.HasKey(d => d.Id);

    builder.HasOne<Domain>()
        .WithOne()
        .HasForeignKey<Domain>("DomainId");
}
// Produces error
public void Configure(EntityTypeBuilder<DomainVerification> builder)
{
    builder.HasKey(d => d.Id);

    builder.HasOne(d => d.Domain)
        .WithOne()
        .HasForeignKey("DomainId");
}

尝试使用第二种方法创建迁移会引发以下错误:

无法创建类型为“”的“DbContext”。异常“您正在配置之间的关系” “DomainVerification”和“Domain”,但在“DomainId”上指定了外键。外键 必须在作为关系一部分的类型上定义。”尝试创建实例时抛出。

出于好奇,如果将第二种语法中的

WithOne()
更改为
WithMany()
,EF Core 就能够生成迁移。到目前为止,我还没有遇到
one-to-one
关系,并且所有实体配置都使用第二种语法(在一对多关系中)。

为什么第二种语法会产生迁移错误?它在模型中定义了导航属性

Domain
,因此它甚至在 LINQ 中可见。

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

这对于一对一关系不起作用的原因是 EF 不知道哪个实体是主要实体以及哪个实体是依赖实体 - 因此您需要使用通用的:

HasForeignKey<Domain>("DomainId")

或非通用:

HasForeignKey("Domain", "DomainId")

(其工作方式是,对于一对多,

WithMany()
返回一个
ReferenceCollectionBuilder<TRelatedEntity,TEntity>
,其中一个
HasForeignKey(String[])
方法,允许您只指定列。但是,
WithOne() 
返回
ReferenceReferenceBuilder<TEntity,TRelatedEntity>
,仅
HasForeignKey
需要指定实体的方法。)

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