ASP.NET Core 6数据种子填充未生效数据库无数据问题求助
ASP.NET Core 6 数据种子填充不生效问题修复方案
核心问题点
- 致命逻辑错误:
Program.cs中种子执行代码写在了app.Run()之后。app.Run()会启动Web主机并阻塞当前执行线程,后续代码在应用运行时永远不会被触发。 - 触发条件限制:原有种子逻辑仅在启动时传入
seeddata命令行参数才会执行,常规启动、调试启动都不会触发填充。 - 外键顺序错误:
DataSeeder中表写入顺序不符合外键约束要求,先写入依赖Seller数据的Product表,再写入Seller表,会触发数据库外键异常导致写入回滚。
修复步骤
1. 修正 Program.cs 执行顺序
将种子逻辑移动到 app.Run() 之前,去掉不必要的命令行参数判断,应用启动完成管道配置后自动执行种子检查,修正后完整代码如下:
using e_commerce.Data; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); // 注册服务 var connectionString = builder.Configuration.GetConnectionString("DefaultConnectionString"); builder.Services.AddDbContext<ShopDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddControllersWithViews(); builder.Services.AddTransient<DataSeeder>(); var app = builder.Build(); // 执行种子数据填充(移到app.Run之前) using (var scope = app.Services.CreateScope()) { var dataSeeder = scope.ServiceProvider.GetRequiredService<DataSeeder>(); dataSeeder.Seed(); } // 配置HTTP请求管道 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
2. 修正 DataSeeder 表写入顺序
按照外键依赖优先级调整写入顺序:先写入无依赖的User、Seller表,最后写入关联前两类数据的Product表,避免外键冲突,修正后Seed方法代码如下:
public void Seed() { // 第一步:写入无外键依赖的Users表 if (!shopDbContext.Users.Any()) { var User_List = new List<User>() { new User() { UserId = 1, FirstName = "David", LastName = "D", Email = "davidd.com", Password = "1234" }, new User() { UserId=2, FirstName = "Alex", LastName = "S", Email="alexs@gmail.com", Password="1234" } }; shopDbContext.Users.AddRange(User_List); shopDbContext.SaveChanges(); } // 第二步:写入Sellers表(仅依赖自身,无其他业务表外键) List<Product_Seller> store_1_product = new List<Product_Seller>(); Product_Seller product1 = new Product_Seller(); product1.SellerID = 1; product1.ProductID = 1; Product_Seller product2 = new Product_Seller(); product2.SellerID = 1; product2.ProductID = 2; store_1_product.Add(product1); store_1_product.Add(product2); if (!shopDbContext.Sellers.Any()) { var Seller_list = new List<Seller>() { new Seller() { SellerId = 1, SellerFirstName = "Da", SellerLastName = "Du", SellerEmail = "abcd@gmail.com", SellerPassword = "1234", SellerPhone = 1900, SellerReview = 5, Products_Sellers = store_1_product }, new Seller() { SellerId = 2, SellerFirstName = "Ng", SellerLastName = "Le", SellerEmail = "bcdez@gmail.com", SellerPassword = "1234", SellerPhone = 1800, SellerReview = 5, ProductID = 1 } }; shopDbContext.Sellers.AddRange(Seller_list); shopDbContext.SaveChanges(); } // 第三步:写入Products表(依赖已写入的Seller数据,不会触发外键错误) List<Product_Seller> MacBook_Sellers = new List<Product_Seller>(); Product_Seller macbook_seller_1 = new Product_Seller(); macbook_seller_1.SellerID = 1; macbook_seller_1.ProductID = 1; Product_Seller macbook_seller_2 = new Product_Seller(); macbook_seller_2.SellerID = 2; macbook_seller_2.ProductID = 1; MacBook_Sellers.Add(macbook_seller_1); MacBook_Sellers.Add(macbook_seller_2); if (!shopDbContext.Products.Any()) { var Product_list = new List<Product>() { new Product() { ProductID = 1, ProductName = "Macbook Pro 2022", ProductImageUrl = "https://i.ibb.co/7nWnHc7/macbookpro.jpg", ProductPrice = 2000.00, Products_Sellers = MacBook_Sellers }, new Product() { ProductID = 2, ProductName = "Dell XPS", ProductImageUrl = "https://i.ibb.co/KXxJsfM/dellxps.jpg", ProductPrice = 1999.00, SellerID = 2 } }; shopDbContext.Products.AddRange(Product_list); shopDbContext.SaveChanges(); } }
补充提示:如果之前已经生成过空数据库,可先删除原有空库,或在种子逻辑前添加
shopDbContext.Database.Migrate()代码,保证表结构先于种子数据创建完成。
内容的提问来源于stack exchange,提问作者đằng dương
相关产品推荐
相关产品推荐

