实体框架实体引用另一个实体两次



我有一个用于接受订单的餐厅应用程序的Product类:

public class Product
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public virtual ICollection<ServingChoice> ServingChoices { get; set; }
}

一种产品可能有多种选择,比如"每日汤"为用户提供了在几种产品中进行选择的机会。产品和选项均为Product:类型

public class ServingChoice
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int ProductId { get; set; }
    public int ChoiceId { get; set; }
    public Product Product { get; set; }
    [InverseProperty("ServingChoices")]
    public Product Choice { get; set; }
}

我做错了什么,因为产品从来没有加载它的选择。该表似乎创建正确。

已编辑

它看起来有点管用,但倒过来了。如果我手动将一些记录广告到数据库中,比如:

ProductID | ChoiceID
1           10
2           10
3           10

它适用于Id为10的产品。

我认为您的问题是因为您没有按照应有的方式映射FK。试试这个:

public class ServingChoice
{
  //...
  [ForeignKey("Product")]
  public int ProductId { get; set; }
  [ForeignKey("Choice")]
  public int ChoiceId { get; set; }
  public Product Product { get; set; }
  [InverseProperty("ServingChoices")]
  public Product Choice { get; set; }
 }

顺便说一句,您正在配置两个一对多关系,但在涉及Product导航属性(在ServingChoice类中)的关系中,您没有定义另一端。如果您想这样做,您应该在Product实体中声明另一个导航属性:

public class Product
{
  [Key]
  //[DatabaseGenerated(DatabaseGeneratedOption.Identity)] this is not necessary, it's the default behavior
  public int Id { get; set; }
  public string Name { get; set; }
  public decimal Price { get; set; }
  public virtual ICollection<ServingChoice> ProductChoices { get; set; }
  public virtual ICollection<ServingChoice> ServingChoices { get; set; }
}

然后,在ServiceChoice类中,您应该在Product导航属性上添加InverseProperty注释,以明确指定关系的另一端:

public class ServingChoice
{
  [Key]
  // [DatabaseGenerated(DatabaseGeneratedOption.Identity)] the same I explain before
  public int Id { get; set; }
  [ForeignKey("Product")]
  public int ProductId { get; set; }
  [ForeignKey("Choice")]
  public int ChoiceId { get; set; }
  [InverseProperty("ProductChoices")]
  public Product Product { get; set; }
  [InverseProperty("ServingChoices")]
  public Product Choice { get; set; }
 }

此外,您可以使用Fluent Api遵循相同的想法:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<ServingChoice>().HasRequired(m => m.Product).WithMany(m => m.ProductChoices).HasForeignKey(m=>m.ProductId);
     modelBuilder.Entity<ServingChoice>().HasRequired(m => m.Choice).WithMany(m => m.ServingChoices).HasForeignKey(m=>m.ChoiceId);
}

最新更新