通过两个不同的实体引用同一实体Ef Core

时间:2019-09-23 22:20:31

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

对此我有些困惑,我正在实现一个愿望清单,其中多个用户可以将相同的实体(产品)添加到他们的清单中。 我扩展了身份用户类并添加了ICollection<Product> 但我似乎无法弄清楚多个用户如何用外键引用同一产品,因为每当一个用户将产品添加到其愿望清单时,由于外键现在引用了新用户,因此该产品会从前一个用户中删除。显然我的逻辑是有缺陷的,我误解了应该如何定义这种关系,能否请您指出正确的方向?

这是产品实体

    public class Product
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public virtual ProductType ProductType { get; set; }

        [ForeignKey("Category")]
        public int SubcategoryFK { get; set; }
        public virtual SubCategory Category { get; set; }
        public decimal Price { get; set; }
        public int NumberOfItems { get; set; }
        public string ImageUrl { get; set; }
        public string IsInStock { get; set; }
        public string ShortDescription { get; set; }
        public string LongDescription { get; set; }

        [ForeignKey("SalesUser")]
        public string SalesUserFK { get; set; }
        public virtual ApplicationUser SalesUser { get; set; }

并且这种关系被配置为

 modelBuilder.Entity<ApplicationUser>()
 .HasMany(a => a.Products)
 .WithOne(p => p.SalesUser).HasForeignKey(z => z.SalesUserFK).OnDelete(DeleteBehavior.ClientSetNull);

1 个答案:

答案 0 :(得分:1)

正如Kei所说,ProductUser的关系是多对多的。在EF Core中,尚不支持没有实体类来表示联接表的Many-to-many关系。但是,可以通过为联接表包括一个实体类并映射两个单独的一对多关系来表示多对多关系。

public class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public virtual ProductType ProductType { get; set; }

    [ForeignKey("Category")]
    public int SubcategoryFK { get; set; }
    public virtual SubCategory Category { get; set; }
    public decimal Price { get; set; }
    public int NumberOfItems { get; set; }
    public string ImageUrl { get; set; }
    public string IsInStock { get; set; }
    public string ShortDescription { get; set; }
    public string LongDescription { get; set; }

    public List<UserProduct> UserProducts { get; set; }
}

public class ApplicationUser:IdentityUser
{
    public List<UserProduct> UserProducts { get; set; }
}

public class UserProduct
{
    public int ProductId { get; set; }
    public Product Product { get; set; }

    public Guid ApplicationUserId { get; set; }

    public ApplicationUser ApplicationUser { get; set; }
}

DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserProduct>()
            .HasKey(up => new { up.ProductId, up.ApplicationUserId });

        modelBuilder.Entity<UserProduct>()
            .HasOne(up => up.Product)
            .WithMany(p => p.UserProducts)
            .HasForeignKey(up => up.ProductId);

        modelBuilder.Entity<UserProduct>()
            .HasOne(up => up.ApplicationUser)
            .WithMany(au => au.UserProducts)
            .HasForeignKey(up => up.ApplicationUserId);
    }

参考:Many-to-many relationshipCascade Delete