我正在尝试使用 EF 6.4.4 和 MySQL 8 通过连接表在 Product 和 Category 之间创建多对多关系,但不幸的是没有成功?
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 = 1)]
public int ProductID { get; set; }
[Key, Column(Order = 2)]
public int CategoryID { get; set; }
public virtual Product Product { get; set; }
public virtual Category Category { get; set; }
}
答案 0 :(得分:0)
我认为您已经创建了两次 productcategory 类。您可以删除第二个并在第一类定义中添加 fk 关系
答案 1 :(得分:0)
您可能需要明确关系映射。我会摆脱 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 核心 <5
对于 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));