SQLite错误19:外键约束失败 EF Core新增预约数据时异常排查
错误原因排查
1. 核心字段映射错误(直接触发外键报错的原因)
你在AddAppointmentBooking方法中,参数ab是AppointmentBooking类型的预约对象:
- 调用
GetPatientById(ab.Id)查询患者时,用的是预约对象自身的主键Id,而非预约关联的患者IDab.PatientId - 给新预约赋值
PatientId = ab.Id,把预约自身的主键当成了患者ID赋值,数据库中不存在对应这个ID的患者,就会触发外键约束失败。
2. 业务逻辑完全颠倒
你的判断逻辑写反了:
var existing = GetPatientById(ab.Id); if (existing != null) { return null; }
插入预约的前提是关联的患者必须存在,现在你判断如果患者存在反而返回null不插入,患者不存在反而继续执行插入,完全不符合业务逻辑,也会导致外键错误。
3. 其他潜在触发外键报错的问题
- 你的
AppointmentBooking类中包含Doctor类型的NameOfDoctor、PreferenceOfAttendance类型的PreferenceOfAttendence导航属性,如果这两个也是关联数据库的实体类,你没有配置对应的外键字段、或者赋值时没有让当前DbContext跟踪对应的实体,EF Core会尝试插入新的关联实体,也可能触发外键约束错误。 - 你的
NameOfServiceDb类中直接手动new了DatabaseContext实例,没有使用依赖注入,如果你在其他地方用DI容器中的上下文插入了患者数据,手动new的上下文如果和DI上下文的数据库配置不一致,也会查不到已存在的患者,触发外键错误。
修复方案
首先修正AddAppointmentBooking方法的字段和逻辑:
public AppointmentBooking AddAppointmentBooking(AppointmentBooking ab) { // 用ab.PatientId查询对应的患者,不是ab.Id var existingPatient = GetPatientById(ab.PatientId); // 患者不存在就返回null/抛异常,不能插入预约 if (existingPatient == null) { return null; } else { var booking = new AppointmentBooking { // 赋值为传入预约的PatientId,不是ab.Id PatientId = ab.PatientId, StartDateTimeBooking = ab.StartDateTimeBooking, NameOfDoctor = ab.NameOfDoctor, PreferenceOfAttendence = ab.PreferenceOfAttendence, DetailOfBooking = ab.DetailOfBooking, }; db.Bookings.Add(booking); db.SaveChanges(); return booking; } }
其次建议:
- 给
Doctor、PreferenceOfAttendance关联属性补充对应的外键字段,比如public int DoctorId { get; set; },赋值时优先赋值外键ID而不是导航属性,避免EF Core自动插入关联实体 - 修改
NameOfServiceDb的构造函数,通过依赖注入注入DatabaseContext,不要手动new实例,保证上下文一致。
内容的提问来源于stack exchange,提问作者user450157
相关产品推荐
相关产品推荐

