如何在实体框架核心中填写自我参考表 [英] how to fill Self Reference Table in entity framework core
问题描述
我在.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屋!