代码优先 - 自我引用一对多关系

Gaa*_*aRa 6 c# entity-framework code-first

我在这里发现了很多类似的问题,但似乎没有一个问题可以解决我的问题.流畅的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");
        //        });
    }
}
Run Code Online (Sandbox Code Playgroud)

数据库中的记录如下:

ID | Name       | ParentID
------------------------------------
1  | First      | 0
2  | SubFirst   | 1
3  | SubSecond  | 1
4  | SubThird   | 2
5  | SubFourth  | 2
Run Code Online (Sandbox Code Playgroud)

那么我的对象在加载实体之后应该如何看待下一步:

   - First
      - SubFirst
         - SubThird
         - SubFourth
      - SubSecond
Run Code Online (Sandbox Code Playgroud)

但是每个对象都有一个空集合.我该怎么做才能让它正常工作?

Moh*_*air 6

您只需通过更正字段而不是像这样导航属性来提及自引用:

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

并在构造函数中初始化导航属性,如下所示:

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

并且还需要覆盖你正在做的但是像这样:

   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 
    }
Run Code Online (Sandbox Code Playgroud)


Sab*_*wan -3

  1. 使用ForeignKey 属性和? 装饰您的UParent 属性。因为它可以为空

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

  1. 在数据库中:如果没有父级,则将 ParentId 值设置为“NULL”。

  • 这 ?无效,因为 UObject 是一个类,而不是值类型。 (3认同)