Pregunta

Say I have a class Box:

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

I want to be able to add boxes to other boxes - a box can HAVE many boxes or BELONG TO one box, but it doesn't need either.

I attempted to model it like this in my project:

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;}
}

However I get the following error addressed in this question:

Unable to determine the principal end of the 'App.Core.Set_ParentSet' relationship. Multiple added entities may have the same primary key.

Removing the ForeignKey attribute lets me build the database, but then cascade deletion doesn't work.

I don't want to create a different class for ChildBox or ParentBox because whether or not a box belongs to / has boxes is going to change all the time in my application.

What is the proper way to model this in EF?

¿Fue útil?

Solución

Try this out.

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;}
}

Otros consejos

A Fluent API version. You can do it with Annotations as suggested by Tyriar. I personally dont like Db junk in my POCOs. So here is an alternative...

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

there is something wrong with BoxID. It is the primary key and the foreign key at the same time? For an example, see http://msdn.microsoft.com/en-us/data/gg193958

The InverseProperty can be used instead of foreign key. This reduces the amount of redundancy.

   [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; }

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top