Отношение один-к-одному в EF Core (дочерняя / зависимая сторона не может быть определена для отношения один-к-одному)
Я получаю следующее сообщение об ошибке и не могу понять причину, почему я его получаю. Интересно, что при добавлении миграций я не получаю никаких ошибок, но всякий раз, когда я хочу использовать контекст, я получаю его.
Дочерняя / зависимая сторона не может быть определена для отношения один-к-одному между "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 ответ
Проблема в вашем Block
а также JobBlock
конфигурации. Согласно вашему требованию эти две конфигурации должны быть следующими:
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.
}
}