【问题标题】:Load related data without foreign key constraint in ef-core-2.1在 ef-core-2.1 中加载无外键约束的相关数据
【发布时间】:2026-02-18 06:30:01
【问题描述】:

我想使用 Eager Loading O/RM 模式加载相关实体数据Parent。但是我不能在ParentId 上指定一个外键约束,因为它会创建一个不允许的循环。目前,我正在使用内部连接显式加载父数据。

这是我正在使用的领域模型。

[Table("Category")]
public class CategoryDM
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    [Display(Name="Parent")]
    public int ParentId { get; set; }
    [NotMapped]
    public CategoryDM Parent { get; set; }
}

有没有办法像这样加载相关实体?或任何其他推荐的方式来实现这一点。

var result = _context.Category.Include(e => e.Parent);

【问题讨论】:

  • it creates a cycle that is not allowed 是什么意思。这称为分层数据,这是一个非常常见的用例,并且与父 id 列完美配合。事实上,我现在正在做的项目中有这个确切的模型。
  • @AvinKavish ParentId 正在与自己建立关系。
  • 是的,没关系。只要确保数据中没有自引用循环,就可以创建关系并将其用于预加载。但这取决于您检查。
  • @AvinKavish 当我指定 FK 时,它在 update-database 上给了我这个错误。 “在表 'Category' 上引入 FOREIGN KEY 约束 'FK_Category_Category_ParentId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束或索引。”

标签: c# entity-framework-core ef-core-2.1 entity-framework-core-2.1


【解决方案1】:

这应该可以正常工作,这是一个示例性的工作模型。

型号

    public class Category : ISelfRelated<Category>
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ThumbnailUrl { get; set; }
        public int? ParentId { get; set; }
        public Category Parent { get; set; }
        public IEnumerable<Category> Children { get; set; }
    }

模型配置

            category.HasOne(c => c.Parent)
                .WithMany(c => c.Children)
                .HasForeignKey(c => c.ParentId)
                .HasPrincipalKey(c => c.Id)
                .OnDelete(DeleteBehavior.Restrict)
                .IsRequired(false);

【讨论】:

  • 非常感谢@AvinKavish。这真的解决了我的问题。