如何在实体框架核心中填写自我参考表 [英] how to fill Self Reference Table in entity framework core

查看:67
本文介绍了如何在实体框架核心中填写自我参考表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.net core 3.1应用程序中使用实体框架核心.我有一个像

I am using entity framework core in my .net core 3.1 application. I have an object like

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; }
 }

在创建模型时,如何使我的对象装载有父对象.模型创建时的当前代码是

How can i make my object loaded with parent object on model creating. current code at model creating is

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

     
}

在创建模型时出现异常

无法将属性或导航父级"添加到实体类型"AppEntity",因为在实体类型"AppEntity"上已经存在具有相同名称的属性或导航.

The property or navigation 'Parent' cannot be added to the entity type 'AppEntity' because a property or navigation with the same name already exists on entity type 'AppEntity'.

推荐答案

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

As the comments said, the OnModelCreating is used to build the relationship between tables.

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

Before loading the object with parent object, you need to change the code in OnModelCreating. The WithOne need to specific an object.

    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")] .

Because you have create the foreign key in dbcontext, so you can remove [ForeignKey("parent_id")].

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

In addition, in model Entity, you should add the property AppEntity to reference the child object.

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

    public AppEntity appEntity { get; set; }
}

然后,您可以使用 Include 包含两个对象.

Then, you can use Include to include the two objects.

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

在一个表中,这将导致循环引用,因为您已经添加了 parent_id 来引用父级.

In one table, this will lead to circular references, because you have added the parent_id to reference the parent.

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

A better solution is to remove public AppEntity Parent { get; set; }, and remove builder.Entity<AppEntity>().HasOne(j => j.Parent).WithOne().HasForeignKey<AppEntity>(f => f.parent_id);.

在将数据插入表中之前,查询entity_id是否存在,如果存在,则添加它,如果不存在,则将其设置为null.因为主键有自己的索引,所以查询速度非常快.

Before inserting data into the table, query whether entity_id exists, if it exists, add it, if it does not exist, set it null. Because the primary key has its own index, the query speed is very fast.

查询时,基于这两列,可以使用子查询或关联查询清楚地处理相应的数据.

When querying, based on these two columns, the corresponding data can be clearly processed using sub-query or associated query.

这篇关于如何在实体框架核心中填写自我参考表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆