You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:54:53