如何修复EF Core种子数据错误:'MenuFoodItem'未提供必填属性'FoodItemId1'
问题:EF Core种子数据报错“FoodItemId1”未提供值
The seed entity for entity type 'MenuFoodItem' cannot be added because no value was provided for the required property 'FoodItemId1'.
问题根源
错误出在CateringDbContext的实体关系配置上:
- 配置
Menu与MenuFoodItem的一对多关系时,错误地将外键指定为FoodItemId,而非MenuId。 - EF Core检测到配置冲突后,自动生成了额外的
FoodItemId1字段作为外键,但种子数据未提供该字段值,导致报错。
同时存在两个潜在问题:
- 实体类中的
List类型导航属性未初始化,可能引发运行时空引用异常。 FoodBooking类中FoodItem导航属性未配置外键,EF会自动生成额外字段,可能引发其他问题。
修复方案
1. 修正实体关系配置
修改CateringDbContext中OnModelCreating方法里的Menu关联配置:
protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<MenuFoodItem>() .HasKey(ms => new { ms.MenuId, ms.FoodItemId }); // 修正Menu与MenuFoodItem的外键配置:外键应为MenuId builder.Entity<Menu>() .HasMany(m => m.MenuFoodItems) .WithOne(fi => fi.Menu) .HasForeignKey(tr => tr.MenuId) // 此处将FoodItemId改为MenuId .OnDelete(DeleteBehavior.Restrict); // 显式指定FoodItem与MenuFoodItem的外键,避免歧义 builder.Entity<FoodItem>() .HasMany(m => m.MenuFoodItems) .WithOne(fi => fi.FoodItem) .HasForeignKey(tr => tr.FoodItemId) .OnDelete(DeleteBehavior.Restrict); // 配置FoodBooking与Menu的关联关系(原代码缺失) builder.Entity<FoodBooking>() .HasOne(fb => fb.Menu) .WithMany() .HasForeignKey(fb => fb.MenuId) .OnDelete(DeleteBehavior.Restrict); // 种子数据部分保持不变 builder.Entity<Menu>().HasData( new Menu { MenuId = 1, MenuName = "Pasta" }, new Menu { MenuId = 2, MenuName = "Pizza" }, new Menu { MenuId = 3, MenuName = "Pies" }, new Menu { MenuId = 4, MenuName = "Carvery" }, new Menu { MenuId = 5, MenuName = "Desert" } ); builder.Entity<FoodItem>().HasData( new FoodItem { FoodItemId = 1, Description = "Tuna Pasta Bake", UnitPrice = 9.99F }, new FoodItem { FoodItemId = 2, Description = "Four Cheese Pizza", UnitPrice = 10.99F }, new FoodItem { FoodItemId = 3, Description = "Chicken and Leak Pie", UnitPrice = 5.65F }, new FoodItem { FoodItemId = 4, Description = "Usual Sunday Carvery", UnitPrice = 12.99F }, new FoodItem { FoodItemId = 5, Description = "Ice Cream with melted Cookies", UnitPrice = 6.99F } ); builder.Entity<MenuFoodItem>().HasData( new MenuFoodItem { MenuId = 1, FoodItemId = 1 }, new MenuFoodItem { MenuId = 2, FoodItemId = 2 }, new MenuFoodItem { MenuId = 3, FoodItemId = 3 }, new MenuFoodItem { MenuId = 4, FoodItemId = 4 }, new MenuFoodItem { MenuId = 5, FoodItemId = 5 } ); builder.Entity<FoodBooking>().HasData( new FoodBooking { FoodBookingId = 1, ClientReferenceId = 1, NumberOfGuests = 1, MenuId = 1 }, new FoodBooking { FoodBookingId = 2, ClientReferenceId = 2, NumberOfGuests = 2, MenuId = 2 }, new FoodBooking { FoodBookingId = 3, ClientReferenceId = 3, NumberOfGuests = 3, MenuId = 3 }, new FoodBooking { FoodBookingId = 4, ClientReferenceId = 4, NumberOfGuests = 4, MenuId = 4 }, new FoodBooking { FoodBookingId = 5, ClientReferenceId = 5, NumberOfGuests = 5, MenuId = 5 } ); }
2. 初始化实体类中的List导航属性
修改FoodItem、Menu类,在构造函数中初始化List,避免空引用:
FoodItem类:
public class FoodItem { [Key] public int FoodItemId { get; set; } [MaxLength(50)] public string Description { get; set; } = null!; public float UnitPrice { get; set; } public List<MenuFoodItem> MenuFoodItems { get; set; } = new List<MenuFoodItem>(); public List<FoodBooking> FoodBookings { get; set; } = new List<FoodBooking>(); }
Menu类:
public class Menu { [Key] [MaxLength(15)] public int MenuId { get; set; } [MaxLength(50)] public string MenuName { get; set; } = null!; public List<MenuFoodItem> MenuFoodItems { get; set; } = new List<MenuFoodItem>(); }
3. 清理并重新生成迁移(若已创建过迁移)
如果之前生成过迁移文件,需删除旧迁移后重新生成并更新数据库:
# 删除项目Migrations文件夹下的所有迁移文件 dotnet ef migrations remove # 重新生成初始迁移 dotnet ef migrations add InitialCreate # 更新数据库 dotnet ef database update
验证修复
完成上述修改后,重新运行数据库初始化代码,种子数据可正常插入,不会再出现FoodItemId1相关错误。
内容的提问来源于stack exchange,提问作者Vortex
相关产品推荐
相关产品推荐

