EF Core 中的一对一关系(无法确定一对一关系的子/依赖方)
Posted
技术标签:
【中文标题】EF Core 中的一对一关系(无法确定一对一关系的子/依赖方)【英文标题】:One-to-one relationship in EF Core (The child/dependent side could not be determined for the one-to-one relationship) 【发布时间】:2019-08-22 13:51:08 【问题描述】:我收到了以下错误消息,但我似乎无法理解为什么会收到它。有趣的是,在添加迁移时我没有收到任何错误,但每当我想使用上下文时,我都会得到它。
无法确定一对一的孩子/依赖方 “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.
【讨论】:
好,但是你不需要/不应该在两个地方配置any(不仅仅是一对一)关系,所以也从JobBlockConfiguration
中删除其他关系配置。
@IvanStoev 是的!你是对的!我没有注意到这一点。非常感谢。
@TanvirArjel 不幸的是,即使配置看起来与您的答案完全相同,我仍然得到相同的结果。错误信息还是一样。
@wegelagerer 我已经在我身边用一个测试项目进行了测试,一切都完美地生成了,没有任何问题。请再次检查您的代码。并请在问题中添加IEntity
基数。
@TanvirArjel - 好吧,承认有点尴尬,但我一直在使用错误的 DbContext(我有 2 个几乎相同):) 我会接受你的回答,因为你给了我有关如何改进配置的宝贵信息以上是关于EF Core 中的一对一关系(无法确定一对一关系的子/依赖方)的主要内容,如果未能解决你的问题,请参考以下文章