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

基于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. 新增角色的扩展方案

若后续新增角色(如药师),仅需三步:

  1. 在Identity中添加Pharmacist角色
  2. 若需关联业务表,在对应实体(如Prescription)中添加PharmacistId及导航属性
  3. 新增角色校验和授权逻辑,无需修改现有表结构

内容的提问来源于stack exchange,提问作者Abel Masingita Hlongwani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:52:29