簡體   English   中英

Code First - 自引用一對多關系

[英]Code First - Self-referencing one to many relation

我在這里發現了很多類似的問題,但似乎沒有一個能幫助我解決問題。 流利的 api 和屬性沒有幫助。 數據庫已創建,但在向其中添加對象時,它崩潰了。 我想要一個包含自身集合的類。 這是我的代碼:

[Table("UObjects")]
public class UObject
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Browsable(false)]
    public long ID { get; set; }
    public string Name { get; set; }
    [Browsable(false)]
    public long? ParentID { get; set; }

    public virtual UObject UParent { get; set; }
    [Browsable(false)]
    public virtual ICollection<UObject> UObjects { get; set; }
}


public class MyContext : DbContext
{
    public DbSet<UObject> UObjects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // This fluent API didn't help
        //modelBuilder.Entity<UObject>()
        //        .HasOptional(u => u.UParent)
        //        .WithMany(u => u.UObjects)
        //        .HasForeignKey(u => u.ParentID);

        //modelBuilder.Entity<UObject>()
        //        .HasOptional(u => u.UParent)
        //        .WithMany(u => u.UObjects)
        //        .Map(c =>
        //        {
        //            c.MapKey("ParentID");
        //            c.ToTable("UObjects");
        //        });
    }
}

數據庫中的記錄是這樣的:

ID | Name       | ParentID
------------------------------------
1  | First      | 0
2  | SubFirst   | 1
3  | SubSecond  | 1
4  | SubThird   | 2
5  | SubFourth  | 2

那么接下來我的對象應該如何加載實體:

   - First
      - SubFirst
         - SubThird
         - SubFourth
      - SubSecond

但是每個對象都有一個空集合。 我應該怎么做才能使其正常工作?

您只需要通過更正字段而不是像這樣導航屬性來提及自我引用:

 [ForeignKey("UParent")]    // EF need for self reference
 public long? ParentID { get; set; }

在構造函數中,像這樣初始化導航屬性:

  public UObject()       
    {
        // this is necessary otherwise EF will throw null object reference error. You could also put ?? operator check for a more interactive solution.  
        UObjects = new List<UObject>(); 
    }

並且還需要像你一樣重寫但是像這樣:

   protected override void OnModelCreating(DbModelBuilder modelBuilder)     
    {   
        // folowwing is also necessary in case you're using identity model     
        base.OnModelCreating(modelBuilder);               
        modelBuilder.Entity<UObjects>()       
            .HasOptional<UObjects>(u => u.UParent) // EF'll load Parent if any     
            .WithMany(u => u.UObjects);        // load all childs if any 
    }

在 EF Core 中可以使用與您的實體類幾乎相同的實體類。 我將您的屬性ParentID重命名為UParentID並添加了構造函數。

[Table("UObjects")]
public class UObject
{
  protected UObject()
  {
    UObjects = new List<UObject>();
  }

  public UObject(UObject parent, string name)
    : this()
  {
    Name = name;
    UParent = parent;
    UParent?.UObjects.Add(this);
  }

  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public long ID { get; set; }
  public string Name { get; set; }
  public long? UParentID { get; set; }

  public virtual UObject UParent { get; set; }
  public virtual ICollection<UObject> UObjects { get; set; }
}

ApplicationDBContext我只有這個:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.Entity<UObject>();
}

用法(查看root對象的屬性如何填充正確的值): 預加載

注意:我沒有在意這段代碼中的刪除。 如果你需要它,事情可能會變得更復雜。

  1. 用 ForeignKey 屬性裝飾你的 UParent 屬性? 因為它可以為空

[ForeignKey("ParentID")] public virtual UObject? UParent { get; set; }

  1. 在數據庫中:如果沒有父級,則將 ParentId 值設置為“NULL”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM