EF Core 中的一对一关系 (无法确定一对一关系的子/从属方)

9
我一直收到以下错误消息,但似乎无法理解为什么会出现此错误。有趣的是,当我添加迁移时没有出现任何错误,但每当我想要使用上下文时就会出现这个错误。
“Block.JobBlock”和“JobBlock.Block”之间的一对一关系无法确定子/从属方。 要识别关系的子/从属方,请配置外键属性。 如果这些导航不应成为同一关系的一部分,则在不指定反向关系的情况下进行配置。
一个Job可以拥有多个JobBlocks(一对多);单个Block只能有一个JobBlock(一对一)。 因此,JobBlock是用于引用Job及其Blocks的引用表/实体。 值得注意的是,JobBlock中的主键由两个键组成,因此它是一个复合主键。
有人认为Block实体应已包含IdJob属性,而JobBlock实体可以完全被取消,但还是有一些理由不能这样做,所以让我们按原样保留 :) 模型:
public class Job : IEntity
{
    public Job()
    {
        JobBlocks = new HashSet<JobBlock>();
    }

    public Guid Id { get; set; } = Guid.NewGuid();
    public ICollection<JobBlock> JobBlocks { get; set; }
}

public class Block : IEntity
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public JobBlock JobBlock { get; set; }
}


public class JobBlock : IEntity
{
    public Guid IdJob { get; set; }
    public Job Job { get; set; }

    public Guid IdBlock { get; set; }
    public Block Block { get; set; }
}

EF配置:

public class JobConfiguration : IEntityTypeConfiguration<Job>
{
    public void Configure(EntityTypeBuilder<Job> builder)
    {
        builder.HasKey(p => p.Id);
        builder.Property(p => p.Id) .IsRequired() .ValueGeneratedNever();

        builder.HasMany(e => e.JobBlocks)
            .WithOne(e => e.Job)
            .HasForeignKey(p => p.IdJob);
    }
}

public class BlockConfiguration : IEntityTypeConfiguration<Block>
{
    public void Configure(EntityTypeBuilder<Block> builder)
    {
        builder.HasKey(p => p.Id);
        builder.Property(p => p.Id).IsRequired().ValueGeneratedNever();

        builder.HasOne(e => e.JobBlock)
            .WithOne(e => e.Block)
            .HasForeignKey<JobBlock>(p => new { p.IdJob, p.IdBlock });
    }
}

public class JobBlockConfiguration : IEntityTypeConfiguration<JobBlock>
{
    public void Configure(EntityTypeBuilder<JobBlock> builder)
    {
        builder.HasKey(p => new { p.IdJob, p.IdBlock });
        builder.Property(p => p.IdJob).IsRequired();
        builder.Property(p => p.IdBlock).IsRequired();

        builder.HasOne(e => e.Job)
            .WithMany(e => e.JobBlocks)
            .HasForeignKey(p => p.IdJob);

        builder.HasOne(e => e.Block)
            .WithOne(e => e.JobBlock)
            .HasForeignKey<JobBlock>(p => new { p.IdJob, p.IdBlock });
    }
}
1个回答

8
问题出在你的BlockJobBlock配置上。根据你的要求,这两个配置应该如下所示:
public class BlockConfiguration : IEntityTypeConfiguration<Block>
{
    public void Configure(EntityTypeBuilder<Block> builder)
    {
        builder.HasKey(p => p.Id);
        builder.Property(p => p.Id).IsRequired().ValueGeneratedNever();

        builder.HasOne(e => e.JobBlock)
            .WithOne(e => e.Block)
            .HasForeignKey<JobBlock>(p => p.IdBlock); // <--- Here it is
    }
}
public class JobBlockConfiguration : IEntityTypeConfiguration<JobBlock>
{
    public void Configure(EntityTypeBuilder<JobBlock> builder)
    {
        builder.HasKey(p => new { p.IdJob, p.IdBlock });

        // Key property is always required. You don't need to specify it explicitly.

        // You don't need to need specify one-one-one configuration
        //  between `Job and Block` and between `Block and JobBlock` in
        //  two places. You need to specify
        //  it only one place. That's why I have removed these from here.
    }
}

3
好的,但你不需要/不应该在两个地方配置任何(不仅仅是一对一)关系,因此也要从JobBlockConfiguration中删除另一个关系配置。 - Ivan Stoev
2
@IvanStoev 是的!你是正确的!我没有注意到这一点。非常感谢。 - TanvirArjel
@TanvirArjel 很不幸,即使配置看起来与您的答案完全相同,我仍然得到了相同的结果。错误消息仍然是一样的。 - wegelagerer
@wegelagerer 我已在我的测试项目中进行了测试,一切都完美生成,没有任何问题。请再次检查您的代码。并且请将"IEntity"基类添加到问题中。 - TanvirArjel
1
@TanvirArjel - 好的,有点尴尬要承认,但我一直在使用错误的DbContext(我有两个几乎相同的) :) 我会接受你的答案,因为你给了我有价值的信息来改进配置。 - wegelagerer
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接