EF Core 7:如何用Marriage中间表配置Person与Spouses的自关联关系?
问题分析与解决方案
错误原因
你当前的配置用HasOne(p => p).WithMany(p => p.Spouses)试图构建一对多关系,但配偶关系属于双向多对多自关联,而UsingEntity是多对多关系专属的配置方法,一对多对应的ReferenceCollectionBuilder类确实没有这个方法,因此抛出错误。
正确配置步骤
1. 修正实体类语法错误
首先要移除实体属性名上的双引号(C#不允许属性名带引号):
public class Person { [Key] public int Id { get; set; } public string Name { get; set; } public virtual List<Person> Children { get; set; } = new List<Person>(); public virtual List<Person> Parents { get; set; } = new List<Person>(); public virtual List<Person> Spouses { get; set; } = new List<Person>(); } public class Marriage { public int PersonId { get; set; } public int SpouseId { get; set; } public virtual Person Person { get; set; } public virtual Person Spouse { get; set; } [DataType(DataType.Date)] public DateTime MarriageDate { get; set; } [DataType(DataType.Date)] public DateTime DivorceDate { get; set; } }
2. 配置配偶多对多自关联关系
使用HasMany+WithMany构建多对多关系,通过UsingEntity绑定中间表Marriage:
modelBuilder.Entity<Person>() // 声明当前Person拥有多个配偶 .HasMany(p => p.Spouses) // 反向关联同样是多对多(配偶关系双向) .WithMany() // 指定中间表为Marriage .UsingEntity<Marriage>( // 配置Marriage的Person导航属性与Person实体的关联,外键为PersonId join => join.HasOne(m => m.Person) .WithMany() .HasForeignKey(m => m.PersonId), // 配置Marriage的Spouse导航属性与Person实体的关联,外键为SpouseId join => join.HasOne(m => m.Spouse) .WithMany() .HasForeignKey(m => m.SpouseId), // 设置Marriage的复合主键,避免重复存储同一配偶关系 join => join.HasKey(m => new { m.PersonId, m.SpouseId }) );
补充说明
- 因为是自关联多对多,两边的导航属性都是
Spouses,所以WithMany()中可以省略反向导航声明;如果需要显式指定,也可以写成.WithMany(p => p.Spouses),效果完全一致。 - 复合主键
{ PersonId, SpouseId }能确保数据库中不会重复存储同一对配偶的婚姻记录。
内容的提问来源于stack exchange,提问作者Currie Dail
相关产品推荐
相关产品推荐

