当前位置: 首页 > news >正文

(二)RestAPI 毛子(Tags)


文章目录

  • 项目地址
  • 一、给Habit添加Tags
    • 1.1 创建Tags
      • 1. 创建一个新的HabitTags实体
      • 2. 设置Habit和Tags的关系
      • 3. 设置HabitTag表
      • 4. 在HabitConfiguration里配置
      • 5. 将表添加到EFCore里
      • 6. 迁移数据
    • 1.2 给Habit增加/修改标签
      • 1. 创建UpsertHabitTagsDto
      • 2. 创建查询HabitWithTagsDto
      • 3. 创建HabitTagsController
    • 1.3 使用Fluent API验证Create tag逻辑


项目地址

  • 教程作者:
  • 教程地址:
  • 代码仓库地址:
  • 所用到的框架和插件:
dbt 
airflow

一、给Habit添加Tags

1.1 创建Tags

1. 创建一个新的HabitTags实体

  • 该实体需要创建一个表,关联Habits和Tags
namespace DevHabit.Api.Entities;

public sealed class HabitTag
{
    public string HabitId { get; set; }
    public string TagId { get; set; }
    public DateTime CreatedAtUtc { get; set; }
}

2. 设置Habit和Tags的关系

  • 在Habit 的是实体里创建关系

在这里插入图片描述

3. 设置HabitTag表

  • 添加HabitTagConfiguration.cs 配置文件

在这里插入图片描述
注意:这里Tag的WithMany()是空的原因是,暂时我们业务上不考虑通过Tag来找所有的Habits; 但是,Habit里面,我们建立了多对多关系,需要通过habit来找到所有的Tag

4. 在HabitConfiguration里配置

  • 修改了Habit的实体,我们需要在HabitConfiguration里配置关系

在这里插入图片描述

5. 将表添加到EFCore里

  • ApplicationDbContext.cs 里,添加新的表

public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : DbContext(options)
{
    public DbSet<Habit> Habits { get; set; }
    public DbSet<Tag> Tags { get; set; }
    public DbSet<HabitTag> HabitTags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema(Schemas.Application);

        modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
    }
}

6. 迁移数据

  1. 在Api的Console里先输入add-migration add HabitTag
  2. 换到docker环境,运行程序,自动执行

1.2 给Habit增加/修改标签

1. 创建UpsertHabitTagsDto

  • 创建UpsertHabitTagsDto,用于处理前端传来的api数据
namespace DevHabit.Api.DTOs.HabitTags;

public sealed record UpsertHabitTagsDto
{
    public required List<string> TagIds { get; init; }
}

2. 创建查询HabitWithTagsDto

  • 用于查询单个habit后,显示该habit里的Tags

public sealed record HabitWithTagsDto
{
    public required string Id { get; init; }
    public required string Name { get; init; }
    public string? Description { get; init; }
    public required HabitType Type { get; init; }
    public required FrequencyDto Frequency { get; init; }
    public required TargetDto Target { get; init; }
    public required HabitStatus Status { get; init; }
    public required bool IsArchived { get; init; }
    public DateOnly? EndDate { get; init; }
    public MilestoneDto? Milestone { get; init; }
    public required DateTime CreatedAtUtc { get; init; }
    public DateTime? UpdatedAtUtc { get; init; }
    public DateTime? LastCompletedAtUtc { get; init; }
    public required string[] Tags { get; init; }
}

3. 创建HabitTagsController

  • 该Controller用于给Habit 处理标签
    [HttpPut]
    public async Task<ActionResult> UpsertHabitTags(string habitId, UpsertHabitTagsDto upsertHabitTagsDto)
    {
        Habit? habit = await dbContext.Habits
            .Include(h => h.HabitTags)
            .FirstOrDefaultAsync(h => h.Id == habitId);

        if (habit is null)
        {
            return NotFound();
        }

        var currentTagIds = habit.HabitTags.Select(ht => ht.TagId).ToHashSet();

        if (currentTagIds.SetEquals(upsertHabitTagsDto.TagIds))
        {
            return NoContent();
        }

        List<string> existingTagIds = await dbContext
            .Tags
            .Where(t => upsertHabitTagsDto.TagIds.Contains(t.Id))
            .Select(t => t.Id)
            .ToListAsync();

        if (existingTagIds.Count != upsertHabitTagsDto.TagIds.Count)
        {
            return BadRequest("One or more tag IDs is invalid");
        }

        habit.HabitTags.RemoveAll(ht => !upsertHabitTagsDto.TagIds.Contains(ht.TagId));

        string[] tagIdsToAdd = upsertHabitTagsDto.TagIds.Except(currentTagIds).ToArray();
        habit.HabitTags.AddRange(tagIdsToAdd.Select(tagId => new HabitTag
        {
            HabitId = habitId,
            TagId = tagId,
            CreatedAtUtc = DateTime.UtcNow
        }));

        await dbContext.SaveChangesAsync();

        return NoContent();
    }

代码解释:

  1. 发起http://localhost:5000/habits/h_0195e900-3c05-7ee6-8b26-7ec6b367d66a/tags请求
  2. 接收一个habitId以及 UpsertHabitTagsDto
    在这里插入图片描述
  3. 根据Id从数据库查询该habit的数据
    在这里插入图片描述
  4. 查看是否有新增或者取消:通过数据库tags所有Id的hashSet和前端传来的进行对比,如果没有变化,则返回204

在这里插入图片描述
5. 排除非法habitId:查询Tags表的tagId和前端传来的Id进行对比,如果有不一样的,则报错

在这里插入图片描述
6. 删除Dto里取出的Tag,保存新增的Tags 完成upsert

在这里插入图片描述
7. 发送请求更改Tag
在这里插入图片描述

1.3 使用Fluent API验证Create tag逻辑

http://www.dtcms.com/a/111785.html

相关文章:

  • 第15届蓝桥杯省赛python组A,B,C集合
  • stable diffusion部署ubuntu
  • 识别干扰验证码——Python || Tesseract-OCR
  • 【深度学习】CNN简述
  • Talend API Tester
  • 请求被中止: 未能创建 SSL/TLS 安全通道。
  • Nature Communications|马兰戈尼效应构建空心金字塔微阵列制备高灵敏度柔性电容式压力传感器(健康监测/柔性压力传感/柔性电子/人机交互)
  • Spring 核心技术解析【纯干货版】- XXII:Spring 扫描效率提升模块 Spring-Context-Indexer 模块精讲
  • Lock接口方法介绍
  • JavaScript 中那些不常见的 for 循环命名与高阶用法
  • ModuleNotFoundError: No module named ‘matplotlib_inline‘
  • C++进阶知识复习 31~38
  • SSL证书自动化管理(ACME协议)工作流程介绍
  • 小动物多导生理记录仪产品需求定义
  • 12.青龙面板自动化我的生活
  • 01背包问题:详细解释为什么重量维度必须从大到小遍历。
  • SignalR给特定User发送消息
  • Spring event 和 MQ的区别及应用场景
  • 《Linux内存管理:实验驱动的深度探索》【附录】【实验环境搭建 4】【Qemu 如何模拟numa架构】
  • Nginx-日志配置
  • 【家政平台开发(14)】家政平台PC前端(Element plus)开发指南:从集成到组件应用
  • 【备考高项】附录:商标法(2013年修正 73条全)
  • QEMU源码全解析 —— 块设备虚拟化(14)
  • 深度学习处理文本(10)
  • 解决GraalVM Native Maven Plugin错误:JAVA_HOME未指向GraalVM Distribution
  • 【家政平台开发(15)】解锁Spring Boot:家政平台后端开发全攻略
  • 深度学习处理文本(12)
  • Linux的 /etc/sysctl.conf 笔记250404
  • AI大模型:(二)1.3 linux本地部署通义万相2.1+deepseek视频生成
  • ARM Cortex-A7 处理器支持的汇编指令集全面总结