【问题标题】:Entity Framework many-to-many run on error实体框架多对多错误运行
【发布时间】:2019-11-17 20:07:57
【问题描述】:

我使用 .Net Core 创建了一个网上商店,并且我正在使用 Entity Framework 代码优先迁移。

我尝试实现产品订单、多对多连接,但出现以下错误:

无法确定“ICollection”类型的导航属性“Order.Products”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性

我的实现是:

Order.cs

public class Order 
{
    [Key]
    public int OrderId { get; set; }
    ...
    public virtual ICollection<Product> Products { get; set; }

}

产品.cs

public class Product
{
    [Key]
    public int ProductId { get; set; }
    ...
    public virtual ICollection<Order> Orders { get; set; }
}

OrderProducts.cs

public class OrderProduct
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("Order")]
    public int OrderId { get; set; }

    [ForeignKey("Product")]
    public int ProductId { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

我的上下文:

public class WebShopContext : IdentityDbContext
{
    public WebShopContext(DbContextOptions<WebShopContext> options)
        : base(options)
    {
    }

    public DbSet<Product> Product { get; set; }
    public DbSet<Order> Order { get; set; }
    public DbSet<OrderProduct> OrderProduct { get; set; }
}

我做错了什么?

【问题讨论】:

    标签: .net entity-framework asp.net-core entity-framework-core


    【解决方案1】:

    我会对多对多关系进行一些更改。

    1) 指向另一个Product和Order的映射表

    Order.cs

    public class Order 
    {
        [Key]
        public int OrderId { get; set; }
        ...
        public virtual ICollection<OrderProduct> Products { get; set; }
    
    }
    

    产品.cs

    public class Product
    {
        [Key]
        public int ProductId { get; set; }
        ...
        public virtual ICollection<OrderProduct> Orders { get; set; }
    }
    

    我个人通常将映射表命名为 ProductInOrderProductOrderMapping 之类的名称,以便更清楚地表明它是一个映射。

    我还将在映射实体上使用复合键,以便 OrderId 和 ProductId 一起成为主键。您从 OrderProduct 中删除 Id,然后按照 Ali Dogan 所说的做

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
      modelBuilder.Entity<OrderProduct>().HasKey(sc => new { sc.OrderId, sc.ProductId});});
    }
    

    这里要考虑的一件事是键的顺序。如果您要基于其中一个键比另一个键更多地查询此表,则出于索引原因,您希望它成为第一个。

    【讨论】:

      【解决方案2】:

      添加到 WebShopContext

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
        modelBuilder.Entity<OrderProduct>().HasKey(sc => new { sc.OrderId, sc.ProductId});});
      }
      

      【讨论】:

        【解决方案3】:
        猜你喜欢
        • 2015-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多