Entity Framework 核心 5 - 递归结构错误

Entity Framework Core 5 - Error with recursive structure

我正在尝试设置一个 entity framework class,其中有 4 个字段 link 返回相同类型的其他字段或为空。我的 class 看起来像这样:

public class Patch : EntityBase
{
    [Key]
    public int PatchId { get; set; }

    [ForeignKey("NorthPatchId")]
    public virtual Patch NorthPatch { get; set; }

    [ForeignKey("SouthPatchId")]
    public virtual Patch SouthPatch { get; set; }

    [ForeignKey("EastPatchId")]
    public virtual Patch EastPatch { get; set; }

    [ForeignKey("WestPatchId")]
    public virtual Patch WestPatch { get; set; }
}

如果我只有 NorthPatch 和 SouthPatch,这工作正常,但一旦我添加第三个 EastPatch,我在尝试迁移时收到以下错误:

System.InvalidOperationException: Unable to determine the relationship represented by navigation 'Patch.NorthPatch' of type 'Patch'.

这是一个很酷的错误!我能够复制,并且作为奖励发现了报告的错误并且仍然对 EF Core 开放。

打开错误: https://github.com/dotnet/efcore/issues/21968

类似问题:

解决方法: 删除 [ForeignKey] 属性,并将以下内容用于您的上下文的 OnModelConfiguring。

builder.Entity<Patch>()
    .HasOne(x => x.NorthPatch)
    .WithOne()
    .HasForeignKey(typeof(Patch), "NorthPatchId");

builder.Entity<Patch>()
    .HasOne(x => x.SouthPatch)
    .WithOne()
    .HasForeignKey(typeof(Patch), "SouthPatchId");

builder.Entity<Patch>()
    .HasOne(x => x.EastPatch)
    .WithOne()
    .HasForeignKey(typeof(Patch), "EastPatchId");

builder.Entity<Patch>()
    .HasOne(x => x.WestPatch)
    .WithOne()
    .HasForeignKey(typeof(Patch), "WestPatchId");

@Lucutah 在我写的时候回答了这个问题,但我想 post 这个我发现值得一看的其他解决方案。它有类似的结果,但也会自动维护 East/West 和 North/South 条目之间的关系。尽管这可能远不及性能,具体取决于您要执行的操作。

public class Patch : EntityBase
{
    public int PatchId { get; set; }
    public virtual Patch NorthPatch { get; set; }
    public virtual Patch SouthPatch { get; set; }
    public virtual Patch EastPatch { get; set; }
    public virtual Patch WestPatch { get; set; }
}

在上下文中..

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Patch>().HasKey("PatchId");

        modelBuilder.Entity<Patch>()
           .HasOne(x => x.NorthPatch)
           .WithOne(x => x.SouthPatch)
           .HasForeignKey(typeof(Patch), "NorthPatchId");
        modelBuilder.Entity<Patch>()
           .HasOne(x => x.EastPatch)
           .WithOne(x => x.WestPatch)
           .HasForeignKey(typeof(Patch), "EastPatchId");
    }