Question

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?

Était-ce utile?

La solution

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

Autres conseils

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

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top