Entity Framework Core 5 - 递归结构错误

Posted

技术标签:

【中文标题】Entity Framework Core 5 - 递归结构错误【英文标题】:Entity Framework Core 5 - Error with recursive structure 【发布时间】:2021-04-28 02:08:34 【问题描述】:

我正在尝试设置一个实体框架类,它有 4 个字段链接回相同类型的其他字段或为空。我的班级是这样的:

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'.

【问题讨论】:

【参考方案1】:

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

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

类似问题: Entity Framework Core One-One Self Referencing Relationship fails

解决方法: 删除 [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");

【讨论】:

【参考方案2】:

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

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");
    

【讨论】:

以上是关于Entity Framework Core 5 - 递归结构错误的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework Core 中的日志记录与拦截器

Entity Framework Core中的日志记录与拦截器

Entity Framework Core 中的日志记录与拦截器

Cosmos 的 .NET 5 和 Entity Framework Core (5.0.1) 迁移问题

如何关闭 Entity Framework Core 5 中的所有约定

ASP.NET Core 5 Blazor WASM、gRPC、Entity Framework Core 5:多对多导致堆栈溢出