如何在 entity framework 核心中填写自我参考 Table

how to fill Self Reference Table in entity framework core

我在我的 .net 核心 3.1 应用程序中使用 entity framework 核心。我有一个像

这样的对象
public class AppEntity
 {
        [Key]
        public int entity_id { get; set; }
        [Required]
        public string entityname { get; set; }
        [Required]
        public string short_code { get; set; }
        [Required]
        public int entitytype_id { get; set; }
        public int? parent_id { get; set; }        
        public AppEntity Parent { get; set; }
 }

如何让我的对象在创建模型时加载父对象。当前创建模型的代码是

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<AppEntity>(o => { o.HasIndex(e => e.short_code).IsUnique(true); });   
builder.Entity<AppEntity>().HasOne(j => j.Parent).WithOne().HasForeignKey<AppEntity>(f => f.parent_id);

     
}

我在创建模型时遇到异常

无法将 属性 或导航 'Parent' 添加到实体类型 'AppEntity',因为实体类型 [=] 上已存在同名的 属性 或导航23=].

正如评论所说,OnModelCreating 用于建立 table 之间的关系。

在使用父对象加载对象之前,您需要更改OnModelCreating中的代码。 WithOne需要指定一个对象。

    public DbSet<Entity>   entities { get; set; }
    public DbSet<AppEntity> appEntities { get; set; }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.Entity<AppEntity>(o => { 
            o.HasIndex(e => e.short_code)
            .IsUnique(true); 
        });
        builder.Entity<AppEntity>()
            .HasOne(j => j.Parent)
            .WithOne(i=>i.appEntity)
            .HasForeignKey<AppEntity>(f => f.parent_id);
    }

因为你已经在dbcontext中创建了外键,所以你可以删除[ForeignKey("parent_id")]

此外,在模型 Entity 中,您应该添加 属性 AppEntity 来引用子对象。

 public class Entity
{
    public int id { get; set; }

    public AppEntity appEntity { get; set; }
}

然后,您可以使用Include来包含这两个对象。

    public virtual Entity GetById(int id) 
    { 
        
        var entity = _context.entities
             .Include(y => y.appEntity)
             .FirstOrDefault(x => x.id == id);
        return entity; 
    }

编辑:

在一个 table 中,这将导致循环引用,因为您添加了 parent_id 来引用父项。

更好的解决方案是删除 public AppEntity Parent { get; set; },并删除 builder.Entity<AppEntity>().HasOne(j => j.Parent).WithOne().HasForeignKey<AppEntity>(f => f.parent_id);.

向table插入数据前,先查询entity_id是否存在,存在则添加,不存在则置null。因为主键自带索引,所以查询速度非常快。

查询的时候,基于这两列,使用子查询或者关联查询就可以明确的处理出对应的数据。