One-to-one relationship in EF Core (The child/dependent side could not be determined for the one-to-one relationship)
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.
}
}
wegelagerer
Updated on June 26, 2022Comments
-
wegelagerer almost 2 years
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 multipleJobBlocks
(one-to-many); singleBlock
can have only oneJobBlock
(one-to-one). So basically, aJobBlock
is a reference table/entity used to referenceJob
and itsBlocks
. It is important to mention that a primary key in theJobBlock
entity consists of two keys thus making it a compound primary key.One might argue that a
Block
entity should already contain anIdJob
property and that theJobBlock
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 }); } }
-
Ivan Stoev about 5 yearsGood, but you don't need to / should not configure any (not only one-to-one) relationship in two places, so remove the other relationship configuration from
JobBlockConfiguration
as well. -
TanvirArjel about 5 years@IvanStoev Yes! You are correct! I did not notice this. Thanks a lot.
-
wegelagerer about 5 years@TanvirArjel Unfortunately I still get the same result even though the configurations look exactly as in your answer. Error message is still the same.
-
TanvirArjel about 5 years@wegelagerer I have tested in my side with a test project and everything generated perfectly without any issue. Please check your code again. And please also add the
IEntity
base to the question. -
wegelagerer about 5 years@TanvirArjel
IEntity
is empty, it isn't relevant for this case. Strange, because the code is 1:1 copy of your, but still doesn't work. Thank you anyway, I'll look into it. -
TanvirArjel about 5 years@wegelagerer Better directly copy my code and replace your
Block
andJobBlock
configuration. I assume you did not make changes forBlock
block configuration as I have done. -
wegelagerer about 5 years@TanvirArjel - Ok, it's a bit embarassing to admit, but I've been using the wrong DbContext (I have 2 which are almost the same) :) I'll accept your answer since you gave me valuable infos on how to improve the configurations