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

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

我一直收到以下错误消息,我似乎无法理解为什么我得到它。有趣的是,在添加迁移时我没有遇到任何错误,但每当我想使用上下文时,我都会得到它。

无法确定“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 });
    }
}
entity-framework .net-core entity-framework-core ef-fluent-api entity-framework-core-2.2
1个回答
2
投票

问题在于你的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.
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.