简体   繁体   English

EF Core中的一对一关系(无法确定一对一关系的孩子/受抚养人一方)

[英]One-to-one relationship in EF Core (The child/dependent side could not be determined for the one-to-one relationship)

I've been getting the following error message and I can't seem to grasp the reason why have I been getting it. 我一直在收到以下错误消息,但我似乎无法理解我得到它的原因。 Interestingly when adding migrations I didn't get any errors, but whenever I want to use the context I do get it. 有趣的是,添加迁移时我没有遇到任何错误,但是每当我想要使用上下文时,我都会得到它。

The child/dependent side could not be determined for the one-to-one relationship between 'Block.JobBlock' and 'JobBlock.Block'. 对于“ Block.JobBlock”和“ JobBlock.Block”之间的一对一关系,无法确定子/从属侧。 To identify the child/dependent side of the relationship, configure the foreign key property. 要标识关系的子级/从属端,请配置外键属性。 If these navigations should not be part of the same relationship configure them without specifying the inverse. 如果这些导航不应该是相同关系的一部分,请在不指定反向关系的情况下进行配置。

A Job can have multiple JobBlocks (one-to-many); 一个Job可以有多个JobBlocks (一对多); single Block can have only one JobBlock (one-to-one). 单个Block只能有一个JobBlock (一对一)。 So basically, a JobBlock is a reference table/entity used to reference Job and its Blocks . 因此,基本上, JobBlock是用于引用Job及其Blocks的引用表/实体。 It is important to mention that a primary key in the JobBlock entity consists of two keys thus making it a compound primary key. 重要的是要提到JobBlock实体中的主键由两个键组成,因此使其成为复合主键。

One might argue that a Block entity should already contain an IdJob property and that the JobBlock entity could be entirely dismissed, but there is some reasoning why it shouldn't be done this way so let's leave it as it is :) 有人可能会争辩说,一个Block实体应该已经包含一个IdJob属性,而JobBlock实体可能会被完全JobBlock ,但是JobBlock某种原因,我们不应该这样处理它,所以我们将其保留为:)

Models: 楷模:

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 Configurations: 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 });
    }
}

Problem is in your Block and JobBlock configuration. 问题出在您的BlockJobBlock配置中。 According to your requirement these two configurations should be as follows: 根据您的要求,这两种配置应如下所示:

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.
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM