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

Sequelize include关联查询如何实现多关联表字段的OR嵌套where条件

EF多关联表OR查询逻辑迁移至Sequelize实现方案

原EF查询逻辑

public async Task<IEnumerable<NotificationAppEntity>> GetPagged(NotificatioAppGetPaggedReq req, Guid userId)
{
    var res = await Context.NotificationApp
        .Where(x => req.Types.Contains(x.NotificationAppTypeId))
        .Include(x => x.CreatedBy).ThenInclude(x => x.UserPics)
        .Include(x => x.Comment)
        .Include(x => x.Task)
        .Include(x => x.Goal)
        .Include(x => x.NotificationAppType)
        .Include(x => x.NotificationAppUserRead)
        .Where(x => x.Task.ProjectId == req.ProjectId.Value || x.Comment.ProjectId == req.ProjectId.Value ||x.Goal.ProjectId == req.ProjectId.Value)
        .OrderByDescending(x => x.CreatedAt)
        .Skip(req.PagingParameter.Skip)
        .Take(req.PagingParameter.Take)
        .ToListAsync();
    return res;
}

问题说明

直接在Sequelize的include关联配置中加where条件会默认用AND拼接,无法实现跨多个关联表字段的OR嵌套筛选。

修正后的Sequelize实现代码

首先确保已导入Sequelize的操作符:

const { Op } = require('sequelize');

实现代码:

async getPagged(userId, body) {
    const notificationApp = await db.NotificationApp.findAll({
        where: {
            // 对应原EF的req.Types.Contains(x.NotificationAppTypeId)
            NotificationAppTypeId: {
                [Op.in]: body.Types
            },
            // 跨关联表的OR筛选逻辑,注意$关联名.字段$的语法
            [Op.or]: [
                { '$Task.ProjectId$': body.ProjectId },
                { '$Comment.ProjectId$': body.ProjectId },
                { '$Goal.ProjectId$': body.ProjectId }
            ]
        },
        offset: body.PagingParameter.Skip,
        limit: body.PagingParameter.Take,
        include: [
            {
                model: db.User,
                attributes: { exclude: hideAttributes },
                as: 'CreatedBy',
                include: { model: db.UserPic, as: 'UserPics' },
            },
            {
                model: db.Comment,
                // 若要和EF的Include行为一致,关联无数据时仍保留主表记录,添加required: false
                required: false
            },
            {
                model: db.Task,
                required: false
            },
            {
                model: db.Goal,
                required: false
            },
            {
                model: db.NotificationAppType,
            },
            {
                model: db.NotificationAppUserRead,
            },
        ],
        order: [['CreatedAt', 'DESC']],
    });
    return notificationApp;
}

核心实现说明

  • 使用$关联别名.字段$语法可以在主查询的where条件中直接引用关联表的字段,Sequelize会自动处理SQL拼接时的表别名映射
  • 将跨表OR逻辑统一写在主查询的where节点下,而非分散在各个include的where配置中,即可实现和原EF一致的多关联字段OR筛选逻辑
  • 注意$包裹的关联别名必须和模型定义关联时配置的as属性完全一致,如果未显式配置as,默认使用关联模型的名称
  • required: false配置会强制使用LEFT JOIN,和EF的Include行为完全一致,避免关联不存在时过滤掉主表记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:48:03