基于ASP.NET Web API、EF Core与Identity,如何关联医患角色与预约、处方表?
解决方案:基于ASP.NET Identity的角色关联设计
核心思路:复用Identity用户表,通过角色区分关联关系
无需为每个角色单独创建数据表,直接利用ASP.NET Identity自带的AspNetUsers表,通过外键关联+角色校验实现业务表与不同角色用户的绑定,新增角色时仅需调整业务逻辑或授权规则,无需修改表结构。
1. 实体类设计(以Appointment和Prescriptions为例)
Appointment实体
public class Appointment { public int Id { get; set; } // 关联患者(Identity用户) public string PatientId { get; set; } public ApplicationUser Patient { get; set; } // 关联医生(Identity用户) public string DoctorId { get; set; } public ApplicationUser Doctor { get; set; } public DateTime AppointmentDate { get; set; } public string Status { get; set; } // 其他业务字段... }
Prescription实体
public class Prescription { public int Id { get; set; } // 关联患者 public string PatientId { get; set; } public ApplicationUser Patient { get; set; } // 关联开处方的医生 public string DoctorId { get; set; } public ApplicationUser Doctor { get; set; } public DateTime IssueDate { get; set; } public string MedicationDetails { get; set; } // 其他业务字段... }
扩展Identity用户(支持角色专属属性)
如果需要给不同角色用户添加专属属性(如医生职称、患者病历号),推荐使用EF Core的表层次继承(TPH),无需新增表:
// 基础用户类,继承IdentityUser public class ApplicationUser : IdentityUser { public string FullName { get; set; } public string PhoneNumber { get; set; } } // 医生专属属性 public class Doctor : ApplicationUser { public string Title { get; set; } // 主任医师/主治医师 public int DepartmentId { get; set; } public Department Department { get; set; } } // 患者专属属性 public class Patient : ApplicationUser { public string MedicalRecordNumber { get; set; } public DateTime DateOfBirth { get; set; } }
EF Core会自动在AspNetUsers表中生成Discriminator字段,区分用户角色类型,无需额外建表。
2. 数据校验与授权控制
在业务逻辑层或API接口中,确保关联用户拥有对应角色:
示例:创建预约时的角色校验
public async Task<Appointment> CreateAppointment(CreateAppointmentDto dto) { var patient = await _userManager.FindByIdAsync(dto.PatientId); if (!await _userManager.IsInRoleAsync(patient, "Patient")) throw new InvalidOperationException("关联用户必须是患者角色"); var doctor = await _userManager.FindByIdAsync(dto.DoctorId); if (!await _userManager.IsInRoleAsync(doctor, "Doctor")) throw new InvalidOperationException("关联用户必须是医生角色"); var appointment = new Appointment { PatientId = dto.PatientId, DoctorId = dto.DoctorId, AppointmentDate = dto.AppointmentDate, Status = "Pending" }; _context.Appointments.Add(appointment); await _context.SaveChangesAsync(); return appointment; }
API接口角色授权
用[Authorize]特性限制接口访问角色,比如仅医生可创建处方:
[Authorize(Roles = "Doctor")] [HttpPost("prescriptions")] public async Task<IActionResult> CreatePrescription([FromBody] CreatePrescriptionDto dto) { // 业务逻辑实现 }
3. 查询优化
查询时可通过角色过滤数据,比如获取指定医生的所有预约:
public async Task<List<Appointment>> GetDoctorAppointments(string doctorId) { // 校验访问权限:仅本人或管理员可查询 if (!User.IsInRole("Admin") && User.FindFirstValue(ClaimTypes.NameIdentifier) != doctorId) throw new UnauthorizedAccessException(); return await _context.Appointments .Include(a => a.Patient) .Where(a => a.DoctorId == doctorId) .ToListAsync(); }
4. 新增角色的扩展方案
若后续新增角色(如药师),仅需三步:
- 在Identity中添加
Pharmacist角色 - 若需关联业务表,在对应实体(如
Prescription)中添加PharmacistId及导航属性 - 新增角色校验和授权逻辑,无需修改现有表结构
内容的提问来源于stack exchange,提问作者Abel Masingita Hlongwani
相关产品推荐
相关产品推荐

