EF中正确的一对多关系

时间:2020-06-13 22:41:21

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

我正在设计一个系统,我的一个实体具有一对多的关系,如下所示。

public class Product
{
    public int Id { get; set; }
}

public class CompetitorProduct
{
    public int Id { get; set; }
    public Product Product { get; set; }
}

competitorProduct表示该产品具有由其他商店出售的同等产品。我应该定义上面或下面所示的一对多关系吗?哪个是正确的?

public class Product
{
    public int Id { get; set; }
    public virtual ICollection<CompetitorProduct> CompetitorProducts{ get; set; }

}

public class CompetitorProduct
{
    public int Id { get; set; }
}

2 个答案:

答案 0 :(得分:2)

假设这是一对多的关系(例如,如果竞争对手的产品与您的多个产品竞争)会发生什么,那么您既可以同时做,也可以添加外键。

public class Product
{
    public int Id { get; set; }
    public virtual ICollection<CompetitorProduct> CompetitorProducts { get; set; }  
}

public class CompetitorProduct
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public virtual Product Product { get; set; }
}

您可以按以下方式使用流利的API来建立您的关系:

modelBuilder.Entity<CompetitorProduct>(entity =>
{
    entity.HasOne(e => e.Product)
          .WithMany(e => e.CompetitorProducts)
          .HasForeignKey(e => e.ProductId)
          .HasConstraintName("FK_ComptetitorProduct_Product");
});

通过这种方式,您可以访问产品中的竞争对手产品以及竞争对手产品中的产品。

答案 1 :(得分:0)

这是我工作过的一个电子商务网站以及我们如何进行表关系的简单示例。

我删除了一堆字段,以便您可以看到真正需要的内容。一旦建立了关系并运行了Add-Migration,只要您在下面的模型中找到了EF,就可以为您处理FK约束。

public class ApplicationUser : IdentityUser
    {
        public ApplicationUser()
        {
            Active = true;
            CreateDateTimeUtc = DateTime.UtcNow;
            ModifiedDateTimeUtc = DateTime.UtcNow;
        }


        [StringLength(500)]
        public string FirstName { get; set; }
        [StringLength(500)]
        public string LastName { get; set; }

        [StringLength(1000)]
        public string Address { get; set; }
        [StringLength(100)]
        public string Unit { get; set; }
        [StringLength(250)]
        public string City { get; set; }
        [StringLength(25)]
        public string State { get; set; }
        [StringLength(20)]
        public string ZipCode { get; set; }

        //This will give access to a list of child carts a user could have
        [Index]
        public bool Active { get; set; }
        public virtual ICollection<Cart> Carts { get; set; }


        // Account Profile Image
        public byte[] ProfileImage { get; set; }
        [StringLength(500)]
        public string ProfileFilename { get; set; }
        [StringLength(100)]
        public string ProfileMimeType { get; set; }

    }

[Table("Cart", Schema = "dbo")]
    public class Cart : AbstractTable
    {
        public Cart()
        {
            IsComplete = false;
        }

        //This create relation to user table where I can get one unique user.
        [StringLength(128)]
        [ForeignKey("ApplicationUser")]
        public string UserId { get; set; }
        public virtual ApplicationUser ApplicationUser { get; set; }


        //These link us to child tables of Cart where we can get a LIST of the items below
        public virtual ICollection<CartCategory> CartCategories { get; set; }
        public virtual ICollection<CartItem> CartItems { get; set; }

        // Marked when a payment/receipt is generated based off of this cart
        public bool IsComplete { get; set; }

    }

[Table("CartItem", Schema = "dbo")]
    public class CartItem : AbstractTable
    {
        //This will return one unique cart id and let us access it as the parent record
        [ForeignKey("Cart")]
        public Guid CartId { get; set; }
        public virtual Cart Cart { get; set; }

        // Signifies if this was paid for in a receipt
        public bool IsComplete { get; set; }

        public virtual ICollection<CartItemCustomField> CustomFields { get; set; }
    }