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'. 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); single Block
can have only one JobBlock
(one-to-one). So basically, a JobBlock
is a reference table/entity used to reference Job
and its 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.
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 :)
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:
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. 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.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With