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

ASP.NET Core控制器中对比不同模型Id查询指定数据

指定时间段可用工位查询实现方案

现有代码存在的问题

  • FindAsync是EF Core提供的主键查询方法,仅支持按实体主键查询单条记录,无法通过外键DeskId筛选某个工位的所有预订数据,你代码中== desk.Id缺少左值的报错就是因为这个方法的参数仅接收主键值,不支持自定义筛选条件
  • Desk实体类的Bookings导航属性类型定义错误,关联的应该是Booking集合而非Person集合
  • 逐工位循环查询数据库的写法会产生N+1查询问题,数据量较大时接口性能会非常差

第一步:修正Desk实体定义

先修正导航属性的类型笔误,配置正确后EF Core可以自动完成Desk和Booking的关联映射:

public class Desk
{
    public Guid Id { get; set; }
    public string Description { get; set; }
    // 修正原类型错误:关联预订集合而非人员集合
    public ICollection<Booking> Bookings { get; set; }
}

第二步:重写接口查询逻辑

直接通过EF Core的关联条件一次性完成筛选,所有过滤逻辑在数据库端执行,性能远高于内存循环遍历:

[HttpGet("available/{start}&{end}")]
public async Task<IEnumerable<Desk>> GetAvailableDesks(DateTime start, DateTime end)
{
    var availableDesks = await _context.Desk
        .Where(desk => !_context.Booking
            .Any(booking => booking.DeskId == desk.Id 
                && booking.Start < end 
                && booking.End >= start))
        .ToListAsync();

    return availableDesks;
}

核心逻辑说明:

  • 用Any判断当前工位是否存在时间冲突的预订记录:只要存在一条预订和传入时间段重叠,该工位就判定为不可用
  • 时间重叠判断逻辑和你原有逻辑一致:当预订开始时间早于查询结束时间、且预订结束时间晚于等于查询开始时间时,两个时间段存在重叠
  • 整个查询会被EF Core转换成单条SQL执行,不会产生多次数据库查询的开销

如果你一定要保留逐循环查询的写法(不推荐,性能差),替换掉原来错误的FindAsync调用即可,筛选匹配DeskId的写法如下:

// 替换原有FindAsync的错误写法
var bookings = await _context.Booking
    .Where(booking => booking.DeskId == desk.Id)
    .ToListAsync();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:15:56