.Net 7电商项目ProductCategories中间表无法填充技术问询
.NET 7 多对多关联表ProductCategories无法填充的问题修复
我在跟着Udemy课程开发电商网站时,为实现Products和Categories的多对多关联创建了ProductCategories表。目前数据库已成功生成该表,Products表也能正常添加数据,但ProductCategories表始终无法被填充。使用的是.NET 7.0.102版本,相关代码如下:
实体类代码
Category.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace shopapp.entity { public class Category { public int CategoryId { get; set; } public string Name { get; set; } public string Description { get; set; } public List<ProductCategory> ProductCategories { get; set; } } }
Product.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace shopapp.entity { public class Product { public int ProductId { get; set; } public string Name { get; set; } public double Price { get; set; } public string Description { get; set; } public string ImageUrl { get; set; } public bool IsApproved { get; set; } public int CategoryId { get; set; } // 冗余字段,需删除 public List<ProductCategory> ProductCategories { get; set; } } }
ProductCategory.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace shopapp.entity { public class ProductCategory { public int CategoryId { get; set; } public Category Category { get; set; } public int ProductId { get; set; } public Product Product { get; set; } } }
DbContext配置代码
ShopContext.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using shopapp.entity; namespace shopapp.data.Concrete.EfCore { public class ShopContext:DbContext { public DbSet<Product> Products { get; set; } public DbSet<Category> Categories { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseMySQL("Server=localhost;port=3306;Database=shopapp2;Uid=root;Pwd=admin;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 原配置外键颠倒,需修正 modelBuilder.Entity<ProductCategory>() .HasOne(pc => pc.Category) .WithMany(pc => pc.ProductCategories) .HasForeignKey(pc => pc.ProductId); modelBuilder.Entity<ProductCategory>() .HasOne(pc => pc.Product) .WithMany(pc => pc.ProductCategories) .HasForeignKey(pc => pc.CategoryId); } } }
数据初始化(Seed)代码
SeedDatabase.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using shopapp.entity; namespace shopapp.data.Concrete.EfCore { public static class SeedDatabase { public static void Seed() { using(var context = new ShopContext()) { if (context.Database.GetPendingMigrations().Count() == 0) { if (context.Categories.Count() == 0) { context.Categories.AddRange(Categories); } if (context.Products.Count() == 0) { context.Products.AddRange(Products); context.AddRange(ProductCategories); // 逻辑依赖Products判断,存在漏洞 } context.SaveChanges(); } } } private static Category[] Categories = { new Category(){ CategoryId=4, Name = "Fashion", Description="Fashion Category"}, new Category(){ CategoryId=5, Name = "Supermarket", Description="Supermarket Category"}, new Category(){ CategoryId=6, Name = "Mom and Baby", Description="Mom and Baby Category"} }; private static Product[] Products = { new Product(){ProductId=11, Name = "Test Product 1", Price=1000, Description="Test Data", ImageUrl="test.jpg", IsApproved=true}, new Product(){ProductId=12, Name = "Test Product 2", Price=1200, Description="Test Data", ImageUrl="test.jpg", IsApproved=true}, new Product(){ProductId=13, Name = "Test Product 3", Price=1400, Description="Test Data", ImageUrl="test.jpg", IsApproved=false} }; private static ProductCategory[] ProductCategories = { // 重复条目+关联不匹配,需修正 new ProductCategory(){CategoryId = Categories[0].CategoryId, Category=Categories[0], ProductId = Products[0].ProductId, Product=Products[2]}, new ProductCategory(){CategoryId = Categories[0].CategoryId, Category=Categories[0], ProductId = Products[0].ProductId, Product=Products[2]}, new ProductCategory(){CategoryId = Categories[0].CategoryId, Category=Categories[0], ProductId = Products[0].ProductId, Product=Products[2]} }; } }
问题修复步骤
1. 修正DbContext的关联配置
外键配置完全颠倒,且缺少复合主键设置,修改OnModelCreating方法:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 设置复合主键 modelBuilder.Entity<ProductCategory>() .HasKey(pc => new { pc.ProductId, pc.CategoryId }); // 正确配置Category关联 modelBuilder.Entity<ProductCategory>() .HasOne(pc => pc.Category) .WithMany(c => c.ProductCategories) .HasForeignKey(pc => pc.CategoryId); // 正确配置Product关联 modelBuilder.Entity<ProductCategory>() .HasOne(pc => pc.Product) .WithMany(p => p.ProductCategories) .HasForeignKey(pc => pc.ProductId); }
2. 删除Product实体中的冗余字段
移除Product.cs中的public int CategoryId { get; set; },避免和多对多关联冲突。
3. 修正Seed数据的ProductCategories
删除重复条目,确保ProductId和关联的Product实例匹配,无需手动赋值Category/Product属性:
private static ProductCategory[] ProductCategories = { new ProductCategory(){CategoryId = Categories[0].CategoryId, ProductId = Products[0].ProductId}, new ProductCategory(){CategoryId = Categories[0].CategoryId, ProductId = Products[1].ProductId}, new ProductCategory(){CategoryId = Categories[1].CategoryId, ProductId = Products[0].ProductId}, new ProductCategory(){CategoryId = Categories[2].CategoryId, ProductId = Products[2].ProductId} };
4. 调整Seed逻辑
将ProductCategories的添加逻辑独立,避免依赖Products的判断分支:
public static void Seed() { using(var context = new ShopContext()) { if (context.Database.GetPendingMigrations().Count() == 0) { if (context.Categories.Count() == 0) { context.Categories.AddRange(Categories); } if (context.Products.Count() == 0) { context.Products.AddRange(Products); } // 独立判断中间表是否需要初始化 if (context.Set<ProductCategory>().Count() == 0) { context.AddRange(ProductCategories); } context.SaveChanges(); } } }
内容的提问来源于stack exchange,提问作者akoluacik
相关产品推荐
相关产品推荐

