[英]Creating a self-referencing Many to Many relationship in Entity Framework 7
[英]Entity Framework Core 3.0 - Creating a self-referencing many to many relationship
所以這是我的問題......我試圖創建的是一個自我引用的多對多關系。 基本上這里是我的 model。
public class InformationSystem
{
public InformationSystem()
{
Systems = new HashSet<InformationSystem>();
ParentSystems = new HashSet<InformationSystem>();
}
[Key()]
public int InformationSystemID { get; set; }
public string InformationSystemName { get; set; }
//Navigation properties
public virtual ICollection<InformationSystem> Systems { get; set; }
public virtual ICollection<InformationSystem> ParentSystems { get; set; }
}
這個想法是一個系統可以有很多父母,父母可以有很多孩子。 我知道如何做一個自我引用的實體,許多孩子可以有一個父母。 讓我絆倒的是多對多的部分。 下面是我的 DbContext。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<InformationSystem>(entity =>
{
entity
.HasMany(e => e.ParentSystems)
.WithMany(e => e.Systems)
.OnDelete(DeleteBehavior.Restrict);
});
但是,在我的 DbContext 上,我收到一個錯誤,即.WithMany 不包含用於接受類型集合輸入的 with many 的定義。 我知道,當代碼首先創建遷移並更新數據庫時,基本上需要構建一個鏈接表。 我認為鏈接表將有兩列並且沒有鍵。 一列是 InformationSystemID,一列是 ParentInformationSystemID。 兩者都是外鍵。 我還知道,要使其正常工作,刪除行為應該受到限制,以便如果在鏈接表中刪除或更新條目,則該更改不會級聯(並創建循環)。 有人可以指出我需要做什么才能讓 EF Core 3 正確執行此操作的正確方向嗎? 如果我必須自己創建一個鏈接表,我將如何做 go? 我需要在我的 DbContext 中做什么? 我知道鏈接表看起來像這樣:
我將不勝感激。
public class InfoSysToParentInfoSys
{
public int InfoSysID;
public virtual InformationSystem InfoSys;
public int ParentInfoSysID;
public virtual InformationSystem ParentInfoSys;
}
在 EF Core 中,必須在 model 中包含一個實體來表示 M:N 關系中的連接表,然后將導航屬性添加到指向連接實體的多對多關系的任一側。
新表S:
public class InformationSystem
{
public InformationSystem()
{
}
[Key()]
public virtual int InformationSystemID { get; set; }
public virtual string InformationSystemName { get; set; }
public virtual ICollection<InformationSystemRelation> Systems { get; set; }
public virtual ICollection<InformationSystemRelation> ParentSystems { get; set; }
}
public class InformationSystemRelation
{
public int ParentId { get; set; }
public InformationSystem Parent { get; set; }
public int ChildId { get; set; }
public InformationSystem Child { get; set; }
}
映射:
modelBuilder.Entity<InformationSystemRelation>()
.HasKey(x => new { x.ParentId, x.ChildId });
modelBuilder.Entity<InformationSystemRelation>()
.HasOne(x => x.Parent)
.WithMany(x => x.Systems)
.HasForeignKey(x => x.ParentId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<InformationSystemRelation>()
.HasOne(x => x.Child)
.WithMany(x => x.ParentSystems)
.HasForeignKey(x => x.ChildId)
.OnDelete(DeleteBehavior.Restrict);
整個樣本:
class Program
{
static void Main(string[] args)
{
var db = new MyDbContext();
var is1 = new InformationSystem() { InformationSystemName = "is1" };
var is2 = new InformationSystem() { InformationSystemName = "is2" };
var is3 = new InformationSystem() { InformationSystemName = "is3" };
var is4 = new InformationSystem() { InformationSystemName = "is4" };
db.InformationSystems.Add(is1);
db.InformationSystems.Add(is2);
db.InformationSystems.Add(is3);
db.InformationSystems.Add(is4);
db.SaveChanges();
var r1 = new InformationSystemRelation() { ParentId = 1, ChildId = 2 };
var r2 = new InformationSystemRelation() { ParentId = 1, ChildId = 3 };
var r3 = new InformationSystemRelation() { ParentId = 4, ChildId = 2 };
var r4 = new InformationSystemRelation() { ParentId = 2, ChildId = 3 };
var r5 = new InformationSystemRelation() { ParentId = 2, ChildId = 4 };
db.InformationSystemRelations.Add(r1);
db.InformationSystemRelations.Add(r2);
db.InformationSystemRelations.Add(r3);
db.InformationSystemRelations.Add(r4);
db.InformationSystemRelations.Add(r5);
db.SaveChanges();
var o2 = db.InformationSystems.Include(x => x.Systems).Include(x => x.ParentSystems).Single(x => x.InformationSystemID == 2);
}
}
public class InformationSystem
{
public InformationSystem()
{
}
[Key()]
public virtual int InformationSystemID { get; set; }
public virtual string InformationSystemName { get; set; }
public virtual ICollection<InformationSystemRelation> Systems { get; set; }
public virtual ICollection<InformationSystemRelation> ParentSystems { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<InformationSystem> InformationSystems { get; set; }
public DbSet<InformationSystemRelation> InformationSystemRelations { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<InformationSystem>(entity =>
{
modelBuilder.Entity<InformationSystemRelation>()
.HasKey(x => new { x.ParentId, x.ChildId });
modelBuilder.Entity<InformationSystemRelation>()
.HasOne(x => x.Parent)
.WithMany(x => x.Systems)
.HasForeignKey(x => x.ParentId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<InformationSystemRelation>()
.HasOne(x => x.Child)
.WithMany(x => x.ParentSystems)
.HasForeignKey(x => x.ChildId)
.OnDelete(DeleteBehavior.Restrict);
});
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("data source=(local)\\SQLEXPRESS;Initial catalog=Test;Integrated security=SSPI");
base.OnConfiguring(optionsBuilder);
}
}
public class InformationSystemRelation
{
public int ParentId { get; set; }
public InformationSystem Parent { get; set; }
public int ChildId { get; set; }
public InformationSystem Child { get; set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.