如何在 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。因为主键自带索引,所以查询速度非常快。
查询的时候,基于这两列,使用子查询或者关联查询就可以明确的处理出对应的数据。
我在我的 .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。因为主键自带索引,所以查询速度非常快。
查询的时候,基于这两列,使用子查询或者关联查询就可以明确的处理出对应的数据。