微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

EF Code First 多对多关系会创建重复的连接表吗?

如何解决EF Code First 多对多关系会创建重复的连接表吗?

我正在尝试使用 EF 6.4.4 和 MysqL 8 通过连接表在 ProductCategory 之间创建多对多关系,但不幸的是没有成功?

public class AppDbContext : DbContext
{
    //Schema Tables
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<ProductCategory> ProductCategories { get; set; }
}

public abstract class BaseEntity
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
}
public class Product : BaseEntity
{
    public virtual IList<Category> Categories { get; set; }
}
public class Category : BaseEntity
{
    public virtual IList<Product> Products { get; set; }
}

现在对于连接表我试过这个:

public class ProductCategory
{
    [Key,Column(Order = 1)]
    public int ProductID { get; set; }
    [Key,Column(Order = 2)]
    public int CategoryID { get; set; }
    
    public Product Product { get; set; }
    public Category Category { get; set; }
}

还有这个:

public class ProductCategory : BaseEntity
{
    public int ID { get; set; }

    [ForeignKey(nameof(Product)),Column(Order = 1)]
    public int ProductID { get; set; }
    [ForeignKey(nameof(Category)),Column(Order = 2)]
    public int CategoryID { get; set; }

    public Product Product { get; set; }
    public Category Category { get; set; }
}

还有这个:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    
    modelBuilder.Entity<ProductCategory>().HasKey(x => new { x.ProductID,x.CategoryID });
}

真正的问题是无论我做什么 EF 都会创建一个重复的连接表?

products
categories
productcategories
productcategory1 (duplicate)

编辑:显然您不能根据 this 帖子和 this 一二执行此操作,但有一种解决方法

// a workaround for the problem
public abstract class BaseEntity
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
}

public class Product : BaseEntity
{
    public virtual IList<ProductCategory> ProductCategories { get; set; }
}
public class Category : BaseEntity
{
    public virtual IList<ProductCategory> ProductCategories { get; set; }
}
public class ProductCategory
{
    [Key,Column(Order = 2)]
    public int CategoryID { get; set; }

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

解决方法

我认为您已经创建了两次 productcategory 类。您可以删除第二个并在第一类定义中添加 fk 关系

,

您可能需要明确关系映射。我会摆脱 DbContext 中的 ProductCategories DbSet。如果这是 EF6 或 EF Core 5,那么我将完全摆脱 ProductCategory 实体定义,特别是如果表只包含两个 FK/复合键:

EF 6

modelBuilder.Entity<Product>()
    .HasMany(x => x.Categories)
    .WithMany(x => x.Products)
    .Map(x => {
        x.ToTable("ProductCategories");
        x.MapLeftKey("ProductId");
        x.MapRightKey("CategoryId");
    });

EF 核心

对于 EF Core 2/3,多对多需要更多地映射为多对一对多,其中每一侧的集合都需要声明为 ProductCategory 实体。

public class Product
{
    // ...
    public virtual ICollection<ProductCategory> ProductCategories { get; set; } = new List<ProductCategory>();
}

public class Category
{
    // ...
    public virtual ICollection<ProductCategory> ProductCategories { get; set; } = new List<ProductCategory>();
}

EF 核心 5

EF Core 5 添加了 UsingEntity 以帮助定义多对多关系的联接表,使产品具有类别(而不是产品类别)和类别具有产品(同样)。

modelBuilder.Entity<Product>()
    .HasMany(x => x.Categories)
    .WithMany(x => x.Products)
    .UsingEntity<ProductCategory>(
        x => x.HasOne(pc => pc.Product).WithMany().HasForeignKey(pc => pc.ProductId),x => x.HasOne(pc => pc.Category).WithMany().HasForeignKey(pc => pc.CategoryId));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。