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

ASP.NET Core Web API中,用户与计划一对多关系下如何设置当前计划?

问题描述

我正在开发ASP.NET Core Web API项目,User与Plan已实现正常的一对多关系。现在希望在多端(Plan)中设置“当前计划”,即除User实体中存储的所有计划列表外,还要指定单个计划为当前计划。

我的Plan类:

public class Plan
{
    public Plan() { }

    public Plan(string name, string description, User user)
    {
        this.Name = name;
        this.Description = description;
        this.Workouts = new HashSet<Workout>();
        this.User = user;
        this.UserId = user.Id;
        this.status = PlanStatus.UnStarted;
    }
    [Key]
    public int PlanId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string UserId { get; set; }
    [ForeignKey("UserId")]
    public virtual User User { get; set; }
    public PlanStatus status;
    public virtual ICollection<Workout> Workouts { get; set; }
}

PlanStatus枚举:

public enum PlanStatus
{
    Unstarted,
    InProgress,
    Completed
}

我的User类:

public class User : IdentityUser
{

    public User() {
    }
    public User(string name, string email)
    {
        this.UserName = name;
        this.Email = email;
        this.Plans = new HashSet<Plan>();
        this.Exercises = new HashSet<Exercise>();
    }
    public virtual ICollection<Plan> Plans { get; set; }
    public virtual ICollection<Exercise> Exercises { get; set; }
}

我想到两种方案:一是在User类中添加currentPlanId,但需要维护;二是通过检查用户所有Plan的PlanStatus,将处于InProgress状态的计划作为当前计划(同一时间仅一个计划处于该状态)。请问哪种方案更好,或是有其他实现方式?


方案分析与建议

方案一:User类添加CurrentPlanId

优点

  • 查询效率高:直接通过User的关联字段获取当前计划,无需遍历或过滤所有Plan,用户计划数量较多时性能优势明显。
  • 逻辑直观:当前计划的关联关系明确,业务代码无需额外处理状态判断逻辑。

缺点

  • 一致性维护成本高:切换当前计划、完成计划时,需同步更新CurrentPlanId和旧计划状态(若需要),业务代码复杂度提升,易出现数据不一致问题。

方案二:通过PlanStatus.InProgress标记当前计划

优点

  • 语义贴合:InProgress本身代表计划正在执行,与“当前计划”的业务语义完全匹配,无需额外冗余字段。
  • 天然唯一性:可通过数据库约束或业务逻辑保证同一用户仅存在一个InProgress状态的Plan,避免数据冲突。

缺点

  • 查询成本略高:每次获取当前计划需过滤用户所有Plan,需为Plan表的UserId和status字段添加联合索引优化性能,否则计划数量大时会影响效率。
  • 状态切换需严谨:启动新计划时,必须先将旧的InProgress计划改为Completed或Unstarted,否则会出现多个当前计划的情况。

推荐选择

如果“当前计划”的核心语义就是“正在执行的计划”,优先选方案二,它让状态与业务逻辑深度绑定,减少冗余。但需注意两点:

  1. 数据库层面添加联合唯一约束:对Plan表的UserId和status字段设置约束,确保同一用户最多一个InProgress计划。
  2. 封装状态切换逻辑:编写统一的方法(如SetAsCurrentPlan),自动处理旧计划状态变更和新计划状态设置,避免手动操作出错。

若业务中“当前计划”不一定等于“正在执行的计划”(比如用户可标记已完成计划为当前参考),则选方案一,此时需在业务代码中严格维护CurrentPlanId的一致性,比如更新计划状态、删除计划时同步更新该字段。

其他实现方式

  • 单独创建UserCurrentPlan关联表:适用于未来可能扩展多当前计划的场景,但当前需求下过于复杂,增加数据库结构冗余,不推荐。

内容的提问来源于stack exchange,提问作者Judith Black

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 10:16:19