.NET Core使用Bogus生成多对多数据时遇EF Core迁移重复键错误
解决Bogus生成StudentLaptop种子数据时的重复主键问题
你遇到的错误核心原因是:StudentLaptop的复合主键(StudentId, LaptopId)出现了重复值。你的代码通过f.PickRandom(students).Id和f.PickRandom(laptops).Id随机生成关联关系,当生成15条数据时,由于5个学生×3个笔记本总共只有15种唯一组合,随机挑选必然会产生重复(除非刚好覆盖所有组合,但概率极低),违反了主键唯一性约束。
以下是两种可行的修复方案:
方案1:生成所有唯一的学生-笔记本关联组合
如果需要覆盖所有可能的关联关系,直接生成学生与笔记本的笛卡尔积即可,完全避免重复:
修改DataGenerator.Initialize方法中的fakeStudentLaptop生成逻辑:
// 生成所有学生和笔记本的组合 var fakeStudentLaptop = fakeStudent .SelectMany(student => fakeLaptop.Select(laptop => new StudentLaptop { StudentId = student.Id, LaptopId = laptop.Id })) .ToList();
如果需要打乱组合顺序,可追加随机排序:
var fakeStudentLaptop = fakeStudent .SelectMany(student => fakeLaptop.Select(laptop => new StudentLaptop { StudentId = student.Id, LaptopId = laptop.Id })) .OrderBy(_ => Guid.NewGuid()) .ToList();
方案2:用Bogus生成不重复的随机组合
如果不需要覆盖所有组合,只想生成指定数量的不重复随机关联,可以通过维护已使用组合集合来避免重复:
修改StudentLaptopFaker类:
public class StudentLaptopFaker : Faker<StudentLaptop> { private readonly HashSet<(Guid StudentId, Guid LaptopId)> _usedCombinations = new(); public StudentLaptopFaker(List<Student> students, List<Laptop> laptops) { RuleFor(sl => sl.StudentId, f => f.PickRandom(students).Id); RuleFor(sl => sl.LaptopId, (f, sl) => { // 循环直到找到未使用的组合 Laptop laptop; do { laptop = f.PickRandom(laptops); } while (_usedCombinations.Contains((sl.StudentId, laptop.Id))); _usedCombinations.Add((sl.StudentId, laptop.Id)); return laptop.Id; }); } }
注意:此方式需确保生成的数量不超过总可能组合数(此处为15),否则会进入无限循环。
额外排查建议
你可以开启敏感数据日志,方便后续快速定位类似主键冲突问题:
在AppDbContext.OnConfiguring方法中添加:
optionsBuilder.EnableSensitiveDataLogging();
内容的提问来源于stack exchange,提问作者Arda Şen
相关产品推荐
相关产品推荐

