【问题标题】:How to model self-referencing object type?如何对自引用对象类型进行建模?
【发布时间】:2013-03-02 02:52:33
【问题描述】:

假设我有一个类 Box:

public class Box
{
    [Required]
    [Key]
    int BoxId { get; set; }
    string BoxName { get; set; }
}

我希望能够将盒子添加到其他盒子 - 一个盒子可以有很多盒子或属于一个盒子,但它也不需要。

我试图在我的项目中这样建模:

public class Box
{
    [Required]
    [Key, ForeignKey("ParentBox")]
    int BoxId { get; set; }
    string BoxName { get; set; }
    int ParentBoxId { get; set; }
    Box ParentBox { get; set; }
    List<Box> Boxes {get; set;}
}

但是,this question 中解决了以下错误:

无法确定主端 'App.Core.Set_ParentSet' 关系。多个添加的实体 可能有相同的主键。

删除 ForeignKey 属性可以让我构建数据库,但随后级联删除不起作用。

我不想为 ChildBox 或 ParentBox 创建不同的类,因为一个盒子是否属于/有盒子在我的应用程序中会一直发生变化。

在 EF 中对此进行建模的正确方法是什么?

【问题讨论】:

    标签: c# entity-framework ef-code-first entity-framework-5 self-reference


    【解决方案1】:

    试试这个。

    public class Box
    {
        [Required]
        [Key]
        public int BoxId { get; set; }
    
        public string BoxName { get; set; }
    
        public int ParentBoxId { get; set; }
    
        // The foreign key for the Box that points at ParentBox.BoxId  (the [Key])
        [ForeignKey("ParentBoxId")]
        public Box ParentBox { get; set; }
    
        // The foreign key for the Boxes that point at this.BoxId (the [Key])
        [ForeignKey("ParentBoxId")]
        public virtual ICollection<Box> Boxes {get; set;}
    }
    

    【讨论】:

    • +1 很好的例子,我使用了 FluintMapping - 并且必须完全一样。
    • 非常感谢。像魅力一样工作。
    • 使用 InverseProperty
    【解决方案2】:

    Fluent API 版本。您可以按照 Tyriar 的建议使用注释来完成。 我个人不喜欢我的 POCO 中的 Db 垃圾。所以这里有一个替代方案......

    modelBuilder.Entity<Box>().
      HasOptional(e => e.ParentBox).
      WithMany().
      HasForeignKey(p => p.ParentBoxID);
    

    【讨论】:

      【解决方案3】:

      BoxID 有问题。既是主键又是外键? 例如,请参阅 http://msdn.microsoft.com/en-us/data/gg193958

      可以使用 InverseProperty 代替外键。这减少了冗余量。

         [Table("Box")]
      public class Box
      {
      
          [Required]
          [Key]
          [Column("BoxId")]
          public virtual int BoxId { get; set; }
      
          [Column("Name")]
          public virtual string Name { get; set; }
      
          [Column("ParentBoxID")]
          public virtual int? MyParentBoxId { get; set; }
      
          [ForeignKey("MyParentBoxId")]
          public virtual Box Parent { get; set; }
      
          [InverseProperty("Parent")]
          public virtual ICollection<Box> Boxes { get; set; }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-06
        • 1970-01-01
        • 2023-03-06
        • 2020-02-23
        相关资源
        最近更新 更多